|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" ?# k! v- I% s4 L( q, s: T
2 #include <cstring> //for memcpy,memset
' S# m/ M, |5 @; |5 Y6 l 3 - j/ E0 S1 u& ^/ R$ b7 B
4 using namespace std;
5 @( {5 g$ B% @" `0 I' G! X 5
+ F0 J( X& j6 p( r8 e. t 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
1 @' R, |7 D& q1 r+ {1 w0 ~ 7 :_round(round)
& c3 w1 U) y9 ? 8 ,_isNetByte(isNetByte) { % U( J1 ^9 ?% F6 r
9 if (key != 0) , p: n7 j( m9 S
10 memcpy(_key, key, 16);
0 r, K$ E8 H- U11 else ; V! I5 W6 R' h4 O
12 memset(_key, 0, 16); " Q) T/ t3 @ _7 {6 A% E
13 }
* ~0 H' B+ J8 q/ k$ V0 k14
2 h0 |2 X9 I& k9 M$ k: c15 TEA::TEA(const TEA &rhs) ; q' m9 M5 l( R! Q$ O% U
16 :_round(rhs._round) : c9 r- S: q; a$ r+ q5 Z6 u
17 ,_isNetByte(rhs._isNetByte) {
; d- j, `: _) c8 Q18 memcpy(_key, rhs._key, 16); ( B- n2 z: W2 C% O
19 }
! D* z2 X1 I3 z! K- S8 T20
" S+ V Y0 H: Z4 @7 H: K; l7 E21 TEA& TEA::operator=(const TEA &rhs) { K4 C: c( @8 G# W# `* S' R* F
22 if (&rhs != this) {
6 t0 |; J9 t) k, E; M8 t4 ~- O23 _round = rhs._round; ) Y# o* Q" j/ N' {- q
24 _isNetByte = rhs._isNetByte;
& D- F' O4 V5 q& @: D8 o! y25 memcpy(_key, rhs._key, 16); % c# X' Z2 V3 n( f: P5 r% ~+ t
26 } ' a( i5 n* o) h" R
27 return *this; 4 s- u" Z4 }0 w. l8 j2 `9 _; A
28 } 6 {4 D6 A1 R; P z+ A- y- f
29 9 q [! r( ?2 v# F- f
30 void TEA::encrypt(const byte *in, byte *out) {
/ k5 z1 C) {+ b! q ~31 encrypt((const ulong*)in, (ulong*)out);
/ n" H8 {$ v5 @) b+ J32 } - ?! w g/ z: O+ k4 b
33
5 d w- p h* N* i34 void TEA::decrypt(const byte *in, byte *out) { & V3 F; m7 E5 K! H! ?5 }7 j+ E
35 decrypt((const ulong*)in, (ulong*)out); - o5 [8 M: Y8 o) d7 m, N" I
36 } 7 T9 S* B# l" @* ]3 z2 u
37
: i0 I3 w1 s+ J+ B" `9 J) B38 void TEA::encrypt(const ulong *in, ulong *out) { " A5 X* R: \1 v h
39 ; t9 e& m8 i8 I7 o
40 ulong *k = (ulong*)_key;
) m$ A: I& p! N% _; m1 O+ Q! q9 l( ]+ g41 register ulong y = ntoh(in[0]); ! d2 z% ~7 j8 ]1 [2 W; c
42 register ulong z = ntoh(in[1]); " w+ I0 k) H' T) x
43 register ulong a = ntoh(k[0]); & ~' n: R- S% o- d* K* l! K
44 register ulong b = ntoh(k[1]);
6 l* }9 ~+ T1 r9 X4 G% \$ Y45 register ulong c = ntoh(k[2]); 3 Z( b7 Q0 y& q2 Q
46 register ulong d = ntoh(k[3]);
2 {4 m8 F' f h9 n( O- w47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 5 g2 U* `& ^) L' G4 w' k
48 register int round = _round; , f- i! y' M+ H$ {% B* h- F: E
49 register ulong sum = 0;
) Q7 N/ i5 k4 a4 _5 d& e50 1 n- t8 U9 G4 E& K) z/ S, l' u
51 while (round--) { /* basic cycle start */ * ?$ J+ W6 d$ x5 c4 w
52 sum += delta; : M2 f4 f: Y6 K* y. e8 n2 v7 y
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
( ]. J; g% x' B/ y8 h% o54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
2 F$ b0 e8 b& u! B' `55 } /* end cycle */ & J! a# C# m) G2 L6 `- {
56 out[0] = ntoh(y); + |# o% ~+ R- G# S
57 out[1] = ntoh(z); - p* O$ O2 V& B
58 } : f4 d: F9 Y, n$ ?
59 " B: ^5 Q. F! L6 U1 z4 {7 g$ M
60 void TEA::decrypt(const ulong *in, ulong *out) { # \- t8 J8 F' H# b8 S
61
- b) z) b, _4 S2 |$ E62 ulong *k = (ulong*)_key;
0 J( E3 K5 c( X& Y1 \- j* u63 register ulong y = ntoh(in[0]);
. E, X2 U) q$ T5 k2 M7 U64 register ulong z = ntoh(in[1]); # N% M6 p( m+ d, X% u
65 register ulong a = ntoh(k[0]); 4 t- N0 c. a9 F
66 register ulong b = ntoh(k[1]); 3 S9 O& J2 F- F2 E" }& E. m7 q
67 register ulong c = ntoh(k[2]);
! p& [) N1 @+ \2 l3 x+ M: W$ F68 register ulong d = ntoh(k[3]); * I) I6 K) ]0 s* u
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 3 a: o3 ? x8 J' }. d! \
70 register int round = _round;
0 R( Y+ d8 i, F8 o71 register ulong sum = 0;
9 ]9 [& S+ W4 L4 M6 c72 / e5 B) e* N+ u' t9 ?
73 if (round == 32) * N' r3 d6 r% E! @- R1 I
74 sum = 0xC6EF3720; /* delta << 5*/ " o7 A% {. `" t1 ~! N
75 else if (round == 16) $ j- ?, T0 d% |$ z6 S* [# D
76 sum = 0xE3779B90; /* delta << 4*/
' m. f8 I. ^0 T" w+ S77 else 0 r( }- G4 k, _' p- c) N$ G/ m' ]
78 sum = delta << static_cast<int>(logbase(2, round)); 5 u5 t* L$ k+ o m9 x! G8 V2 V
79
" C; [( R ^" Q n, v8 Y: A! k80 while (round--) { /* basic cycle start */ 4 ~: W+ e. ~. i* V9 E4 a. Y
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); 6 I+ m6 {5 S1 j3 z. [0 `9 L h; H
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
4 w0 J/ _ q2 [$ v1 C3 ?& s ~* |83 sum -= delta;
9 t5 E9 o! A9 k5 R9 q- u2 S8 G5 f84 } /* end cycle */
8 ?( ~0 ?" T+ [85 out[0] = ntoh(y);
) e: n! {' a# @/ P+ @86 out[1] = ntoh(z); + S Y5 t& B3 v' G }3 b
87 }
) {, y# b$ `+ \! s& \* H) _
5 V/ Z; i7 s+ l1 i需要说明的是TEA的构造函数: 0 G, N# o" C( @6 }, F+ r
TEA(const byte *key, int round = 32, bool isNetByte = false); : W2 h" N I, l, i1 l
1.key - 加密或解密用的128-bit(16byte)密钥。
; f! h! j! ~0 \2.round - 加密或解密的轮数,常用的有64,32,16。
) V( b% w# |6 G+ T3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! 8 W. z- S ~2 ^/ B+ k R g- T
2 n9 ~7 [' _; v+ V& r: n
最后当然少不了测试代码: |
|