|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" 1 F) \4 ]( r( A5 d3 l
2 #include <cstring> //for memcpy,memset
5 A. |8 g# B( c2 u2 C! ~2 d 3
- x) R4 i2 C& e, d 4 using namespace std;
2 E6 z5 s( m @" M3 {- p# t 5 0 s$ e4 z! ~* c, K" s0 T* C' n
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
2 ~3 {8 z2 [( s6 r# M0 A. P- I 7 :_round(round)
$ H3 P( |( v: P& ^' a( K2 x" d 8 ,_isNetByte(isNetByte) { / A9 g4 @$ e9 u6 w' }$ |5 T8 k
9 if (key != 0)
2 ]" M2 W z% u* u0 A( y10 memcpy(_key, key, 16);
2 C Y# z: M0 `! |4 F( t$ Q/ b11 else : q& D9 e, l8 [( w/ T. N& @
12 memset(_key, 0, 16);
: ~6 r* v! c: z+ k13 } 2 y7 R9 v( d& L. d1 R
14
% x o, ^" o) t, k15 TEA::TEA(const TEA &rhs) 9 c( w( X# ?- W. j0 S& s' q: m0 E
16 :_round(rhs._round) $ G' o/ [. E3 q" @& [4 A
17 ,_isNetByte(rhs._isNetByte) {
* p: `/ p! u2 Z" P& n18 memcpy(_key, rhs._key, 16); % t! \8 [5 ~3 x+ N
19 } ! h( K# z3 g7 n2 w8 r. r7 a, p
20 ( s, O- f( s; q0 O) H
21 TEA& TEA::operator=(const TEA &rhs) { Y# X6 {% q8 `3 D% W) u) _3 o9 M' S
22 if (&rhs != this) { + S$ H' L9 R( d3 A. ^
23 _round = rhs._round; 1 _' B- i' Q# t, d/ z( m
24 _isNetByte = rhs._isNetByte;
2 H P8 E' p7 i25 memcpy(_key, rhs._key, 16); & c" e X. w! n# R4 ~$ i. f& j
26 }
0 b" c9 ?& x& l5 y0 D- s0 i' \# D7 ?27 return *this; 0 ]4 c7 L8 g' m3 d0 ?, n( g8 J" y7 Z. Y
28 } ) ~2 u) w d3 B. D1 _
29
% y& ~( G$ ~) n30 void TEA::encrypt(const byte *in, byte *out) { & t" y* c% d; t# _! w
31 encrypt((const ulong*)in, (ulong*)out); 0 ]3 f: j9 [( H" p
32 }
' N& S# K, l+ `7 L33
3 h5 M5 \6 L. D9 V* r! ~34 void TEA::decrypt(const byte *in, byte *out) { b$ a. B; O1 K& e$ L9 e3 {! Z5 ]
35 decrypt((const ulong*)in, (ulong*)out); $ {! v- w* {" A
36 } - T/ O! `) ]/ S
37 ) @8 X& a7 R$ w0 M" f
38 void TEA::encrypt(const ulong *in, ulong *out) { % Q. x4 s( k$ O0 \& I
39 0 [+ ]6 O$ ]/ s
40 ulong *k = (ulong*)_key; 9 T: j- J Y3 T" a% B3 |. c
41 register ulong y = ntoh(in[0]); ( e2 Z5 d/ |, o H, V
42 register ulong z = ntoh(in[1]);
- T( a6 \- M0 ^- t2 |! _43 register ulong a = ntoh(k[0]);
1 b7 \" i7 O! @7 k: `5 ~$ _$ I44 register ulong b = ntoh(k[1]);
' K- J3 q( G) m' D* D6 |) u45 register ulong c = ntoh(k[2]);
# q, l1 t. l3 X! [- M8 G1 W* \& p46 register ulong d = ntoh(k[3]); 9 ^9 \+ E! ]3 b2 B
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
* s" Q( ?6 Q; ]) ?4 e: A48 register int round = _round;
3 i0 B: J; w8 l$ C49 register ulong sum = 0; * y6 f4 W. f. ?, {- p. Z" `9 p0 S
50 ( P4 J, ?$ [; N& q' o
51 while (round--) { /* basic cycle start */ * @" D2 R1 u) P5 o
52 sum += delta; 6 m+ J5 Q8 ^. ^
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
2 `% D Y. f1 G Q% g0 C4 U) O8 n, _3 N54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); 1 o5 q( \" x' s8 E, K5 N
55 } /* end cycle */
9 x+ e4 _0 U( q1 C56 out[0] = ntoh(y);
4 O4 r8 p. q7 P( |) \% N57 out[1] = ntoh(z); 4 A4 [* h: v6 }$ f) n/ s( i
58 } + G) ^6 `4 o. M
59
5 R) F' {$ z" C60 void TEA::decrypt(const ulong *in, ulong *out) {
; }% J1 R) q0 X% o- I: l& y61
, h' l/ A& Y1 r$ L62 ulong *k = (ulong*)_key; & A2 j" E7 Q( O7 a
63 register ulong y = ntoh(in[0]);
3 y4 y M) X; f/ @; v. i64 register ulong z = ntoh(in[1]); + L% ]# R+ [7 G+ l' p3 R
65 register ulong a = ntoh(k[0]);
1 n1 Z" T" t6 R. g0 d8 u66 register ulong b = ntoh(k[1]); 3 \6 Q( |0 b7 R) |0 w& O
67 register ulong c = ntoh(k[2]);
7 e% k% @0 t/ w' e& i68 register ulong d = ntoh(k[3]);
! Q; I; w( t# l5 N1 s1 f69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
- P1 p; o+ h& ^/ m7 v5 L70 register int round = _round;
7 L, }" q6 M& W* \: d+ R71 register ulong sum = 0;
5 h0 M$ ~! q# O5 r( I; N" V H" ?. S72
) X5 j" k+ B4 c e73 if (round == 32) S; H' `, n5 j# L' o, p
74 sum = 0xC6EF3720; /* delta << 5*/
+ W, m: e5 f7 q/ D5 v) b& W75 else if (round == 16) 0 K3 `/ s* R( v; Y+ \, K5 X
76 sum = 0xE3779B90; /* delta << 4*/ 7 l) @ Z$ s6 y/ {; V
77 else
4 P- \$ h+ `: }. L78 sum = delta << static_cast<int>(logbase(2, round)); ! E1 d: j. s I: p; ~( ^
79 * G. J2 J" @) V% Q0 L- _/ q
80 while (round--) { /* basic cycle start */ , C! E9 Q0 c- ^
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); ; x, X7 Q4 \) o3 l9 u
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
. v' ?9 d" V/ Y G83 sum -= delta;
# N) q! ^& e( I+ Z84 } /* end cycle */
# v3 G. m7 U8 s- a85 out[0] = ntoh(y);
4 M# m8 n3 x; G& O4 a& D86 out[1] = ntoh(z);
" b) Y# c4 S7 f0 W4 |2 ~- x87 }
2 U+ y9 Y. F9 W, n. |; p% ^, U. d
需要说明的是TEA的构造函数: 1 a- P7 x( M- I2 h
TEA(const byte *key, int round = 32, bool isNetByte = false); / D2 r# _# z n# M
1.key - 加密或解密用的128-bit(16byte)密钥。 - N; B' Q5 O# @) K! }
2.round - 加密或解密的轮数,常用的有64,32,16。
* k# l. {6 N6 l s5 U3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! + ]& e; o% r* d" t, I
6 M. W& _: D# X最后当然少不了测试代码: |
|