|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" 2 h* {% ]( q. |0 P7 b
2 #include <cstring> //for memcpy,memset ; Y% q- q1 e9 r- _9 G6 D
3 # L) ?, T* v4 i4 }/ \
4 using namespace std; 1 l# u/ s/ b7 y" }
5
& \. l+ U0 T# Z9 U 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) ; h Z1 I( ^1 Z8 n. t
7 :_round(round)
5 S/ P2 Q- ]4 Z% @9 t. p, ? 8 ,_isNetByte(isNetByte) { 7 ~5 }% q: k* z! g) b
9 if (key != 0) . `: S+ F8 G& j: ?9 a' T" y
10 memcpy(_key, key, 16); 3 y; u. j; O; A8 C, x0 T2 [" u
11 else ; |5 O, Z7 q" A6 |- P
12 memset(_key, 0, 16);
2 a' B% k& Q- S$ I6 x4 i13 }
. K! \7 L" d" }, t4 R14 " j. x5 v" F) K0 \" k+ `4 g
15 TEA::TEA(const TEA &rhs) ; P+ d" `$ b$ A7 V+ ?! G
16 :_round(rhs._round)
^: e1 b- M# v! _9 I9 E5 O17 ,_isNetByte(rhs._isNetByte) { ; W0 A% ?" v3 q# W& z" W0 j
18 memcpy(_key, rhs._key, 16);
* P0 @( [& K' k- d19 } & H& ^% U( ~$ D9 T: F! I. Z
20
! k: e% Z' y0 q% A21 TEA& TEA::operator=(const TEA &rhs) {
1 k% n9 i4 R( Z, T) c22 if (&rhs != this) { " T& v$ R. Q# ~+ m% {7 R! t, w$ l" }
23 _round = rhs._round;
/ h5 G$ a% c) D) ~24 _isNetByte = rhs._isNetByte; - Y6 s' t/ V6 R
25 memcpy(_key, rhs._key, 16);
8 W+ Z3 v q6 M& b( i/ \( V26 }
5 D0 o2 _1 k# k$ F* r' c" s/ |3 l1 W27 return *this;
; h8 i4 Z8 [/ O; e28 }
: F7 \( F; {' R29
3 c" B1 _9 c! o2 O' U30 void TEA::encrypt(const byte *in, byte *out) { . f$ w! ?; V2 ^. J3 ^5 H! B
31 encrypt((const ulong*)in, (ulong*)out); & }' g2 q9 T" A E& v
32 }
( `- K+ }6 o! I+ {3 T/ t33
3 {4 n4 E- q# N' Y( O34 void TEA::decrypt(const byte *in, byte *out) { 8 N3 b: Y3 b8 U$ D: b% o
35 decrypt((const ulong*)in, (ulong*)out);
2 y+ z4 ]/ J% P. z& ^36 }
& `+ p# J( I% q% C' O; K7 |: G37 & H5 q; w2 E6 }: ?9 a& o, q: x( y
38 void TEA::encrypt(const ulong *in, ulong *out) { . ?) k- S7 i4 j9 m
39
2 r' q" Q) Y& t3 ]40 ulong *k = (ulong*)_key;
& @" ^ l, _, |, l1 Z P41 register ulong y = ntoh(in[0]);
8 ?: Z) ?/ s3 Q! ?! U' C* U2 s$ P1 \2 M42 register ulong z = ntoh(in[1]); ' b) c$ I$ Q6 f& Y% c1 M: X
43 register ulong a = ntoh(k[0]);
- ^- Y. w4 s9 [- c) U44 register ulong b = ntoh(k[1]); ' ?6 }+ W# J8 A$ P4 P/ d
45 register ulong c = ntoh(k[2]); ( J$ M. z0 ?% U
46 register ulong d = ntoh(k[3]);
6 q( \' b0 e/ m1 ^% s, e: z$ N: S47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ & n! M) M1 X- Y5 q
48 register int round = _round;
& r0 h) ?% a# e: Q49 register ulong sum = 0;
0 z" c. d6 z& w7 m6 [: G50
: M3 C! f7 A' }' ~' G51 while (round--) { /* basic cycle start */ 9 ]. g; t/ ^8 Q; J3 x
52 sum += delta;
; y! g0 ?* Y) E7 h* s" a53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); # {5 q2 l: A0 [9 e
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
n" A* L7 o: U) q55 } /* end cycle */ - ~9 o! f* ?# G7 h* g5 D
56 out[0] = ntoh(y); 0 Y L/ Q' Q5 Z8 |1 n
57 out[1] = ntoh(z);
* n6 W3 Q3 n q: i$ ]- A7 S58 }
& u5 \; B% p1 Q; j2 N: c59 ( a7 U' H) ^6 y7 F
60 void TEA::decrypt(const ulong *in, ulong *out) { + f5 l8 ?7 P. g) c
61
& j, n$ W, y' S* b7 A! h( c3 E/ Z+ I: g62 ulong *k = (ulong*)_key; 1 b$ D$ K/ ^5 z
63 register ulong y = ntoh(in[0]);
* c: x1 f; J2 ^' E" C7 }3 e5 _64 register ulong z = ntoh(in[1]); ; f1 t2 K Z" ]. F( V
65 register ulong a = ntoh(k[0]); 4 a1 ]5 J- V* {1 Q; s2 M' N
66 register ulong b = ntoh(k[1]);
0 k* `* V p# G& o; {% }67 register ulong c = ntoh(k[2]);
$ M* g1 v- ^: ~- @( Q8 ]68 register ulong d = ntoh(k[3]);
8 W$ I1 v! _. A$ C) B! @69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 7 S9 r1 D$ B" ^" d4 O0 Q2 G
70 register int round = _round;
4 y: r: X$ O5 y9 H! Z; c, r0 R71 register ulong sum = 0; $ }6 [% | U- }' _5 j/ q
72
* m0 q/ P) n( ]4 q0 ?73 if (round == 32) $ E3 w$ ?9 j: i4 j7 w
74 sum = 0xC6EF3720; /* delta << 5*/
: i" M! _% w/ O- O5 c6 v2 ~0 G% w75 else if (round == 16)
! l5 R: e/ \# w2 U4 c+ E76 sum = 0xE3779B90; /* delta << 4*/
/ n3 o+ ?% N+ Y. s/ e77 else 9 f' P q) M% Y5 F5 k6 f# `$ K
78 sum = delta << static_cast<int>(logbase(2, round));
2 o* g" I2 N) @8 z/ e1 T S79
0 I* l1 L/ c% G. x& t80 while (round--) { /* basic cycle start */
" z x$ o! V O/ D! X) m, A81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
v1 k& y' _' e. s' T6 Q82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); 4 B3 M; {* f& ]! k
83 sum -= delta;
d+ O# A* C. l. \4 N1 R8 ]( F& j84 } /* end cycle */ 3 u5 R4 N! Z5 h& u8 X; r' l0 b
85 out[0] = ntoh(y);
7 R0 g9 l7 [7 B86 out[1] = ntoh(z); 2 U1 Y$ U4 a* ^+ N {$ n! v* @$ r/ `
87 }* o7 s, B/ S D3 E1 y: m6 Q) i
3 ^/ |5 s! l- H e. f& P需要说明的是TEA的构造函数: 2 r# }8 q+ j3 S8 X
TEA(const byte *key, int round = 32, bool isNetByte = false); 7 o8 c: f2 z0 S6 S
1.key - 加密或解密用的128-bit(16byte)密钥。 0 I: J* P5 \2 N: A3 }, M4 ^
2.round - 加密或解密的轮数,常用的有64,32,16。
+ e0 l. t* r* q2 J0 n3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
# u" Z1 C# r# ?7 G2 }5 |6 z/ l: B$ ]6 \# W- _! E
最后当然少不了测试代码: |
|