|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" 6 `' `4 y' P9 ]! N6 Z0 l
2 #include <cstring> //for memcpy,memset * R& n- c" r ] K
3
, i9 ]# K$ ^7 Z) g# u4 {9 j 4 using namespace std; 1 i$ I d+ |5 B' u$ v. Y8 A; U% U
5
3 L3 o6 H2 P& U% ? 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
! q# M# Y* F0 [% S3 z% d 7 :_round(round)
$ J- k1 _$ o4 K7 ]. y4 k" g/ h' w5 } 8 ,_isNetByte(isNetByte) { ) S2 ]& }. y/ b1 v3 `
9 if (key != 0)
; M. e/ [+ B# R8 n/ ^, |/ Z10 memcpy(_key, key, 16); ( @6 o4 M4 a2 _
11 else
! d1 _# w1 f* C2 ]2 l- d- ~12 memset(_key, 0, 16); ! C" p" P. Q& g: Q
13 }
% i. y) t/ I/ ~1 r14 3 L0 D0 T0 J0 a' L" P9 R
15 TEA::TEA(const TEA &rhs) : a! U0 E7 q" w& T8 b& c6 G
16 :_round(rhs._round) . B4 [2 P1 a) C$ G. O" [2 o
17 ,_isNetByte(rhs._isNetByte) { 0 m9 T# A0 B& D# z- N
18 memcpy(_key, rhs._key, 16);
2 \2 }7 }) A/ V( n7 x19 }
2 T' `& V/ w& s3 |% m& |5 ]20 , W* a9 X0 U/ O! H" S8 ?
21 TEA& TEA::operator=(const TEA &rhs) { # ?( ^' y! t! w f" H& i' @
22 if (&rhs != this) { 4 h# e' S; R) A) A
23 _round = rhs._round;
# k5 a/ s: |' Z24 _isNetByte = rhs._isNetByte;
- l# X$ g% _7 _, B* k, T25 memcpy(_key, rhs._key, 16); , Z6 A3 c E M3 B( a- B( j
26 } 1 Y0 k h5 ~+ ?: h z/ k% E& G2 g
27 return *this;
" W3 q: H+ i5 t. C J28 } ; X( j3 F: ?) a9 `
29 * o& s6 T+ W. r
30 void TEA::encrypt(const byte *in, byte *out) { . r. D" e! W4 Y
31 encrypt((const ulong*)in, (ulong*)out);
7 X3 y- l/ U0 C5 m. q) Z32 } 0 h* ? E: B9 G$ ^3 B
33
3 c& |+ {8 ?3 h4 X9 o34 void TEA::decrypt(const byte *in, byte *out) { / t# N9 c" @& t4 D
35 decrypt((const ulong*)in, (ulong*)out); 3 ]0 D8 |; p" X# X, O
36 } 0 z, m& c+ C$ @# }; s
37
9 c. P+ \: C( r; P, G38 void TEA::encrypt(const ulong *in, ulong *out) { 7 V! X/ \# m) |7 V8 I4 D: g
39 : \9 K" |9 y( M
40 ulong *k = (ulong*)_key;
8 v0 I% k) z4 `3 s7 T+ q41 register ulong y = ntoh(in[0]);
; f9 G: S5 \+ G @* i+ R42 register ulong z = ntoh(in[1]);
( D8 g; {9 ^3 d+ y1 M43 register ulong a = ntoh(k[0]);
, t, e$ m' g/ z% X. W44 register ulong b = ntoh(k[1]); , q, q! a4 D2 S3 z% }' [3 B: O# W1 C# r
45 register ulong c = ntoh(k[2]);
( u, b2 i8 f& Y7 N4 T' _46 register ulong d = ntoh(k[3]); . i* b$ x1 h1 A+ Y( K
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
`) z; @: }! `$ v @; q48 register int round = _round; $ E }! d& A: e% |
49 register ulong sum = 0; + F- w" f9 q3 a, X
50 9 S2 g w; D3 k( M i2 `3 g
51 while (round--) { /* basic cycle start */
- }' I4 j& Q k) M- M C52 sum += delta; 1 M& z4 E# v# |6 h6 }& v) G
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
& I! L4 q3 W7 f3 _$ [7 I; L7 u54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); 6 F+ }0 i# s: p* _+ r& b& s3 T
55 } /* end cycle */
7 O. o/ ]) G5 |# d- o3 U56 out[0] = ntoh(y); 1 q$ o, F, C: I! y1 g* A
57 out[1] = ntoh(z); $ z5 s0 o. x4 G! j' h# j a1 h% t
58 } - t) f K. n0 U' F9 @9 ?* n
59 6 t! w+ I( |/ _
60 void TEA::decrypt(const ulong *in, ulong *out) {
M- T9 w: z2 E( U2 Y; h61
3 B4 `9 m3 r5 n; Z62 ulong *k = (ulong*)_key; & \: ~1 o7 B! ]
63 register ulong y = ntoh(in[0]); + r: @0 g2 \% J6 F1 O: Z1 _
64 register ulong z = ntoh(in[1]);
0 v% B1 J- Q, h+ ^' `1 C4 X65 register ulong a = ntoh(k[0]); % t4 o# ]) \% y
66 register ulong b = ntoh(k[1]); 7 e2 Z' v) S9 q0 I; {9 W
67 register ulong c = ntoh(k[2]);
5 h. _' L& E+ x9 c- O68 register ulong d = ntoh(k[3]); 1 V6 d5 [' ^- n9 c& w/ _( y
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
& c, M& \& U. W! \& c70 register int round = _round;
5 S2 q0 ~. I0 h0 d* g) J71 register ulong sum = 0; 6 f( i( p3 |- o6 U: K f% o+ b
72
1 `. |/ l, T3 [/ U* C' X73 if (round == 32) ! g4 U, x' u1 k4 S$ p+ M( P e1 N, H
74 sum = 0xC6EF3720; /* delta << 5*/ 4 A. e$ k2 A6 q
75 else if (round == 16) 5 \" n$ H# y& O9 q# f+ \ @/ H. ^
76 sum = 0xE3779B90; /* delta << 4*/ 7 w) m; \6 Y& e- o3 O5 ^% M& @4 b
77 else 8 e" o y8 |/ e
78 sum = delta << static_cast<int>(logbase(2, round)); ' o: l3 m% ^+ ` G. a1 }
79
3 p" m8 V/ g+ k1 Y80 while (round--) { /* basic cycle start */ + e( I- k& A# _% h' F
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); , Z- g- [- j+ Z% F" G) @
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
2 X \# i9 |2 T ]2 n1 t83 sum -= delta;
. {1 U0 j6 N* Y84 } /* end cycle */
6 e7 D5 W" S, J& d8 n! [85 out[0] = ntoh(y); ; k3 d6 v& `) w) L2 Q$ @/ ?& k
86 out[1] = ntoh(z);
8 x# Z1 w7 t" p% e" _87 }: Z x$ k1 ]+ c) V
8 x, ~- a7 U2 \) t2 R/ H
需要说明的是TEA的构造函数:
! B7 ^0 |0 r7 L& z$ v1 N9 [; ?" WTEA(const byte *key, int round = 32, bool isNetByte = false); 0 y4 e5 i; d- l) j! O4 l
1.key - 加密或解密用的128-bit(16byte)密钥。 3 M6 ]- r) S; O8 X( O/ a$ I( } @
2.round - 加密或解密的轮数,常用的有64,32,16。
- }. T+ s3 _: \# Y3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
! G+ `6 L% W. l( M0 ]- Z* A" G1 R
最后当然少不了测试代码: |
|