|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
3 L) J- t& r1 g- Q" N! o$ w 2 #include <cstring> //for memcpy,memset % a1 a, \+ S3 c- z4 j; s, m
3 8 L! O# y8 ]8 E3 O5 n% U
4 using namespace std; $ D9 l' u8 Z4 d( @$ Q/ u
5 2 h( U- {7 P& a
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
1 r+ _' S) s; ?+ U/ i5 X: |! B 7 :_round(round)
1 o/ n" r$ n4 ^, F% a4 e! s 8 ,_isNetByte(isNetByte) {
# ~% K6 U" W+ u1 h# p7 i- ^! l C 9 if (key != 0)
6 P3 R! Z* x, X8 H1 d: n: T10 memcpy(_key, key, 16);
7 K% b' B h2 I! w11 else
6 S& j9 E( s% T& @5 s d1 }12 memset(_key, 0, 16); + M* _+ v M3 J& y
13 }
7 Z' I; V M! G. a" P14 + ?& i; E) I- I/ j, f. ^* v& G3 K
15 TEA::TEA(const TEA &rhs) - M9 c. g4 M8 T' g0 q/ y, \
16 :_round(rhs._round) 3 `* S% q( {4 E4 y2 `: o& W* u
17 ,_isNetByte(rhs._isNetByte) {
# r2 ~3 d. g1 S- z* T" g18 memcpy(_key, rhs._key, 16);
* M8 b. A+ x6 J19 } h! J5 G$ [ `: b" p* k
20
; v% J5 S X `1 v21 TEA& TEA::operator=(const TEA &rhs) { - X9 P% ~+ Z7 S
22 if (&rhs != this) {
{0 b" t& `) c, y5 w+ p; C1 s9 [23 _round = rhs._round; 7 w4 q9 B: _; f( ~. e b* k6 \0 A. I
24 _isNetByte = rhs._isNetByte; & q5 N; C+ i4 |0 t1 R9 e& ]
25 memcpy(_key, rhs._key, 16);
, ]+ e7 p! M, j26 }
; E* L% ]9 w# D! `, ]" v; u27 return *this; 2 ?% s" U u$ X# C1 S
28 }
+ ^& t8 h( B2 S5 j/ F5 e( M( N29
" ^) d8 n6 H, z% Y30 void TEA::encrypt(const byte *in, byte *out) {
+ Y: r" w4 R3 l- T; s) w31 encrypt((const ulong*)in, (ulong*)out);
: _ f, e7 U$ T' _; m' _6 |0 A32 } g7 t* B" T' ~% I3 u! U/ `& r4 R+ ^
33
' E$ A7 T* e9 o# C! g1 m+ j' _' b34 void TEA::decrypt(const byte *in, byte *out) {
1 Q m3 C$ k# K& c/ S% b35 decrypt((const ulong*)in, (ulong*)out); 2 p0 L0 z8 S3 y. @) q3 Q, K8 i# |
36 }
, j" _- U* i m6 ^( o37
1 a+ h! [1 r; B38 void TEA::encrypt(const ulong *in, ulong *out) {
; b* F' U+ O3 U. ^/ e$ e39
4 M0 @; F6 z# g) Q/ g1 I) ?40 ulong *k = (ulong*)_key; % c: B# q% P7 X& N4 P' H
41 register ulong y = ntoh(in[0]);
1 z" Y( N8 [5 X" @+ g V42 register ulong z = ntoh(in[1]); 8 s4 u. c ~, Q& Q9 E0 U
43 register ulong a = ntoh(k[0]);
# z( F8 ~8 e7 Y: ^3 \3 w% A44 register ulong b = ntoh(k[1]); & L9 M; n, s9 i% U, c- }
45 register ulong c = ntoh(k[2]); 7 ]' S! T1 Q* f1 F6 C' r5 {& B
46 register ulong d = ntoh(k[3]); 1 v- l# i3 l! }9 H, }6 k4 h8 M
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ + y2 D) ?) Z, |# J
48 register int round = _round;
; X- h: p. A( U/ C" g! i49 register ulong sum = 0;
$ J9 [0 |: z ~6 j* g1 ^50
* q. K- Z3 z9 I% f9 S9 ?51 while (round--) { /* basic cycle start */
7 U6 L) I. X8 i ^' H52 sum += delta; 4 f1 c, a0 g; H8 s$ a w% }9 B
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); 6 H9 N3 n, `3 g! `6 b* Q
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); $ v0 f/ k; E$ J) P: a" M
55 } /* end cycle */
3 J& y7 }: ? r: Y2 E: g' c56 out[0] = ntoh(y);
% h+ h; g; f& f1 U: x5 `8 Z57 out[1] = ntoh(z);
: n5 O% d# }8 N# \9 @7 r" t58 } * w. r6 Y8 `2 `
59 2 X( S7 Z2 @0 D* s q# `9 M! z
60 void TEA::decrypt(const ulong *in, ulong *out) { 7 t3 B& [* d( l5 y* R, a5 ^7 ]4 ^
61
' M: q6 q/ I; q+ j. q62 ulong *k = (ulong*)_key;
+ }" z ]7 l# @+ J63 register ulong y = ntoh(in[0]); % Q8 ?& m( }7 D; Y- s' ?& o( C
64 register ulong z = ntoh(in[1]);
* v0 r' U1 V1 [4 g5 J65 register ulong a = ntoh(k[0]); # q; v6 D& l' p- N6 j. W
66 register ulong b = ntoh(k[1]);
+ O+ b6 u8 w+ q6 ?) G7 s2 ?67 register ulong c = ntoh(k[2]);
+ a: j' n( Y3 t. n: ?% Y68 register ulong d = ntoh(k[3]);
1 ]2 l4 P# T$ Y: V69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ % P3 F9 S& c {0 e+ z( |
70 register int round = _round;
2 M7 q9 ?! P* N) a& ^% I5 R) |+ S71 register ulong sum = 0; + a3 q) `/ {7 g. [- G; U
72
3 K* n; L! `1 |2 i; u# K73 if (round == 32) 5 A" z+ Z, @: {, {6 x
74 sum = 0xC6EF3720; /* delta << 5*/
1 ~! E: j8 H" T O75 else if (round == 16) 9 d" o5 K! x0 v, C* N) b
76 sum = 0xE3779B90; /* delta << 4*/ ' Y. ?# J0 I7 {" I
77 else $ y* ~! J0 _/ t$ Z- ~$ Q3 O/ _
78 sum = delta << static_cast<int>(logbase(2, round));
* N @7 j8 j5 Q79
! D! Y1 v5 ?4 }8 G8 z80 while (round--) { /* basic cycle start */ + K4 r4 c5 r2 J8 O
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); # X: ?3 K/ r( K+ D- w
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
6 u! D1 A3 e4 ?) R1 H3 L3 g83 sum -= delta;
/ t# b+ w/ M6 e8 D, w# K84 } /* end cycle */
" f7 E1 k, c" W4 k5 E85 out[0] = ntoh(y);
% s& H" D0 q: O! i7 N9 c3 S86 out[1] = ntoh(z);
) a+ C2 F: c& X* y( O87 }
# n, c) k- G" w F5 k; M- u0 x# U
! @' s# z- S* a4 P5 O/ q需要说明的是TEA的构造函数: 5 z7 X- s @- H" L+ g' ~/ a9 G
TEA(const byte *key, int round = 32, bool isNetByte = false);
f9 R) Y. U4 l. B6 U3 b1.key - 加密或解密用的128-bit(16byte)密钥。 [" w2 H4 ?& a2 F% S( c
2.round - 加密或解密的轮数,常用的有64,32,16。
! s( k9 [! ?6 O- V( O5 l3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! # `+ M I8 \5 T; k3 ?' p
; `2 K. N q1 c" n5 a0 d
最后当然少不了测试代码: |
|