|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" ) m H* z9 T, x3 i
2 #include <cstring> //for memcpy,memset
6 _$ L$ i2 }1 \( U. {$ a 3
3 v3 k+ ^; M5 s7 p/ ^+ ] 4 using namespace std; # H+ i# z. M; F+ G- [8 ^: t7 u1 p
5 U3 }8 v: U4 J9 z d2 E0 @9 Z" V# z
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) + T9 a' U6 N/ r& B$ E
7 :_round(round) " L/ E$ {8 D7 D M9 D- T2 w0 n
8 ,_isNetByte(isNetByte) { / q6 j% s: O1 w( l
9 if (key != 0) ! D0 y V0 b2 D% k, _
10 memcpy(_key, key, 16);
: P! S# {1 `5 g: C7 K11 else 3 I; F9 Q- k( ~8 G. B
12 memset(_key, 0, 16);
" W3 l0 Q! o7 ~ s* Y13 } % W; A. F9 R1 V {/ J
14 2 x! \: P: Y* P1 B) t" @& H
15 TEA::TEA(const TEA &rhs)
m# W3 w# b/ \+ g16 :_round(rhs._round)
5 k$ P- T& o, c" r17 ,_isNetByte(rhs._isNetByte) { 4 ]- t2 i D& o
18 memcpy(_key, rhs._key, 16);
9 Q" m( x/ d% b4 D& o @% u8 Y" a/ r/ c19 }
1 d9 w! A6 U: [, t, D1 w7 R+ O+ P) r20 5 g: M9 L% T) L p2 H# s1 o
21 TEA& TEA::operator=(const TEA &rhs) { 3 ?0 }& F, [; F
22 if (&rhs != this) {
( O: j7 ^: Q, {/ u. h' o) ~; h3 D23 _round = rhs._round; 6 T3 _0 [! F" O
24 _isNetByte = rhs._isNetByte; . ^5 ~4 d. c/ ~' C N
25 memcpy(_key, rhs._key, 16);
% O" ]' z' h+ Z. ~" o26 }
* K; G: U, u6 i+ Y* W( c: n/ R S27 return *this;
D7 X. V8 Q' P5 H3 n9 T6 A% ?28 } 9 d- u2 P' R5 s( A; x; R3 ?
29 ) }! d5 V& R6 f( J( n3 R& V1 \6 d
30 void TEA::encrypt(const byte *in, byte *out) { . x/ [* L; R$ G- p) k
31 encrypt((const ulong*)in, (ulong*)out);
, Z; }& O" @4 R' z6 L32 }
' q. {8 C n( @) `# K2 k4 ~33 ( k* S% z8 f# d0 _0 P" M, l
34 void TEA::decrypt(const byte *in, byte *out) {
% {' C8 Q# y, F5 |) n35 decrypt((const ulong*)in, (ulong*)out); - _) q, V7 F! q1 y
36 }
7 v- y4 `; X7 ~, f% G3 k5 j37
! O2 ^. m/ _# r" \7 G% E38 void TEA::encrypt(const ulong *in, ulong *out) { 0 W5 A9 @8 S" ^; G
39
, ] |, ^3 y2 g4 Q40 ulong *k = (ulong*)_key; ; n, e$ {" {+ ?1 |- Y5 J
41 register ulong y = ntoh(in[0]);
" T/ s4 A7 b7 c L# [. K) M/ A7 J5 r42 register ulong z = ntoh(in[1]); i7 I/ k! k: u* x
43 register ulong a = ntoh(k[0]); ! ?; g( T; d4 ?5 [7 U* q( g
44 register ulong b = ntoh(k[1]);
9 f5 l$ k8 ?0 H) e45 register ulong c = ntoh(k[2]);
' [& Y% N: i' o% Z. |46 register ulong d = ntoh(k[3]); / Z- {8 C* O, C, }: \/ u
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
* W% @. G* ^* q7 R, b48 register int round = _round;
* [! f4 }" t9 t n( _, j6 [49 register ulong sum = 0; 3 U7 Q' l6 |. u* A' b$ o' J
50
0 O6 g( t8 E9 r; N L; [51 while (round--) { /* basic cycle start */ : I y9 u) Z. v' s( T
52 sum += delta;
" |0 n( ] ` i; M. U53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
6 x+ b+ J$ \+ e, V7 h% U1 F9 i5 x54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); ; j7 S6 w$ ?; l4 y! U' C' K
55 } /* end cycle */ 2 {& @4 T: A5 p2 k
56 out[0] = ntoh(y);
: }' Q! v6 E' U7 {9 H57 out[1] = ntoh(z);
8 D$ ^9 j; R0 @( U! B9 P58 } ! Z9 Z$ D& B" a, F0 ]7 M- d
59 {; u5 q1 o' K0 Z+ v3 Z$ l; }
60 void TEA::decrypt(const ulong *in, ulong *out) {
4 x/ `! \# W a- D5 h61
5 k$ `5 I9 s+ @; u62 ulong *k = (ulong*)_key; 5 k \- I8 J1 o
63 register ulong y = ntoh(in[0]); ~) O$ Q7 B' l7 I( R. U
64 register ulong z = ntoh(in[1]); 0 N1 @2 |7 Y' P# C- O- P: k" S
65 register ulong a = ntoh(k[0]);
! z; k; m* g: r' @7 J2 B4 Q% O66 register ulong b = ntoh(k[1]);
# O3 N' K; V( f9 |5 \) {67 register ulong c = ntoh(k[2]); + v: a# V; ]6 a
68 register ulong d = ntoh(k[3]);
( O) y, T8 z3 u, q* Y69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
( q3 m9 R J5 \, @70 register int round = _round;
$ n& e7 H+ J# H) U71 register ulong sum = 0;
" M3 ^, i0 w% \5 h6 `72
% ~, R: E0 `0 E73 if (round == 32)
& v# H/ [$ @5 m- ]74 sum = 0xC6EF3720; /* delta << 5*/ # W2 O& A: T- y$ _' |: U. g' T/ V
75 else if (round == 16) , q2 t0 F3 X u/ @
76 sum = 0xE3779B90; /* delta << 4*/ 0 _7 I7 x3 U. E% G6 g
77 else
4 T* `+ @# U8 T$ {5 s78 sum = delta << static_cast<int>(logbase(2, round));
3 C4 n- P( z. H9 n9 z9 s& g f- O79 5 Z% T4 _3 }+ R2 M' _
80 while (round--) { /* basic cycle start */
! H8 J& J8 J7 x( w' b) K81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); , U# _5 `8 |8 r2 W
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
( B$ @5 w* `& k8 h8 G8 p83 sum -= delta; $ ]# U, j/ B) N
84 } /* end cycle */
" c' M; Z' v8 b9 R85 out[0] = ntoh(y); 2 U7 ^! C+ T% u9 z0 p( h( ]- K
86 out[1] = ntoh(z); " N/ z' E2 |" l9 _3 @ @; U
87 }0 U* e3 _. ~# K" k0 x; a- P
2 I8 N6 C# X* g4 V5 r
需要说明的是TEA的构造函数:
% \' D( z+ U5 I* y$ f- oTEA(const byte *key, int round = 32, bool isNetByte = false);
: t4 R ?3 W2 S1.key - 加密或解密用的128-bit(16byte)密钥。
) t* g/ A. m5 |- t2.round - 加密或解密的轮数,常用的有64,32,16。 & O( k( f0 _ a: V" K3 J
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! - E& E6 w9 a! G6 P V& ?8 \# a- B; }
7 U+ j8 a* h7 d) a; w最后当然少不了测试代码: |
|