|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" + c$ ]( _) E! C, t$ ]9 I8 P
2 #include <cstring> //for memcpy,memset
* `$ G4 p, d1 Z: j6 c+ C9 L7 x8 u0 ? 3
# g/ ~! V: w9 B7 e7 N4 ^& ]1 f 4 using namespace std; 2 P) t7 o2 D9 ` b8 _5 [7 L
5 ; z! ^/ R1 B& M$ O" F
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
8 Y3 W9 A: Y3 J 7 :_round(round) 1 F7 q) C% V w: p- i# q0 V
8 ,_isNetByte(isNetByte) {
" ] Y7 [1 H9 o3 O! L& F1 O. G 9 if (key != 0) * p' [: g- N9 T0 g6 O7 ~
10 memcpy(_key, key, 16);
9 m, s/ B% @2 L4 k$ e1 }11 else
% R( c% ~: y" e0 L9 X12 memset(_key, 0, 16);
3 u6 S& |; W% O2 o13 } V {) s7 P- e! f: p/ q" J
14 + {% b' ^8 c2 N U6 {/ L1 x% O( z6 v
15 TEA::TEA(const TEA &rhs) : v! _0 S9 O0 o. u4 T4 k
16 :_round(rhs._round) ) ?3 Y( G0 A* ~. B( [0 V
17 ,_isNetByte(rhs._isNetByte) {
" }. l0 v( i/ K5 H' R8 ?- C& X18 memcpy(_key, rhs._key, 16);
1 S+ K( G. ]- t19 } ! o9 `3 E- f1 }2 F# D0 h% q8 a. [
20 ( \- H3 n- y* X0 V' @
21 TEA& TEA::operator=(const TEA &rhs) {
! D; L9 i+ q; u1 ^- ?22 if (&rhs != this) {
+ Q% p) G: r9 M: Y2 J23 _round = rhs._round; 4 X% C7 E+ ^. _7 M$ u
24 _isNetByte = rhs._isNetByte;
9 ]( o7 `# X F; ]6 P% N7 U7 z0 y) o$ R25 memcpy(_key, rhs._key, 16);
( P4 v6 E: A6 h5 j- i7 j8 Z' c- v ?26 }
0 T- k7 G7 |0 }. ]4 H# F, l27 return *this; 5 Y9 ]$ G5 u4 O, x
28 } + i% e" q0 q, s
29
# C6 h: o+ ^& I) F+ s4 W' U$ E/ h30 void TEA::encrypt(const byte *in, byte *out) {
7 w" n5 a. f. ~! s31 encrypt((const ulong*)in, (ulong*)out); / W; @8 D5 t3 A4 `: o9 C
32 }
) W* I# r5 Q7 z7 o8 l33 ' C, V* x9 ^- _9 O x
34 void TEA::decrypt(const byte *in, byte *out) {
% t+ |- c. i" `4 y* b35 decrypt((const ulong*)in, (ulong*)out);
! H! [! _" g) A' e0 g4 U/ b4 c36 }
0 K0 o4 e. T5 u9 x5 c/ J37
& @* k2 ]$ {9 i, D: `38 void TEA::encrypt(const ulong *in, ulong *out) {
" [+ \5 s# X; ]5 z b3 }, X39
& H. \$ O0 V; i3 w- `40 ulong *k = (ulong*)_key; ! u% w8 b4 D3 s) }1 Y
41 register ulong y = ntoh(in[0]);
) C6 h/ z0 s, h4 U- J0 D42 register ulong z = ntoh(in[1]); 6 k5 K% e5 o# D$ ?
43 register ulong a = ntoh(k[0]);
% Y7 h( H+ f9 g8 {8 T44 register ulong b = ntoh(k[1]);
+ _* r% i% ^" {" j L0 A6 F45 register ulong c = ntoh(k[2]);
1 l( Y1 x& K0 W46 register ulong d = ntoh(k[3]);
e2 S2 G& C7 _" ^. o; o47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ : h) j% a5 q& M; m1 e6 r( r+ N5 f
48 register int round = _round;
* x2 n# B, q5 ?/ Y) C49 register ulong sum = 0; 6 q) G3 _* a/ X3 i
50
, g0 |$ Z& {" n9 }3 J1 y9 f51 while (round--) { /* basic cycle start */ ' B {( v( v) y3 _- N6 B( r
52 sum += delta; - _3 r5 m; y; X% B6 U0 s
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); ) c7 |4 ?! S: d9 Z
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
7 X, S9 N" v, H; Z/ ]6 I55 } /* end cycle */
! ^6 d0 l" J) p" @56 out[0] = ntoh(y);
: Q9 @: a: A/ P8 }) E* G/ O! n, R57 out[1] = ntoh(z);
- D3 j5 v, X: ~. H58 } 6 h7 C, f; ~0 ^
59
! W! r( t- L! h. n% E6 j/ n60 void TEA::decrypt(const ulong *in, ulong *out) { + F% L @+ H$ p% [; [& I
61
+ G& i9 @% \) [5 E6 ?1 M8 c+ U62 ulong *k = (ulong*)_key;
1 G, a9 \2 v. T, a P( l63 register ulong y = ntoh(in[0]); 4 E9 g) }" D2 a* |( F* i, v: Z
64 register ulong z = ntoh(in[1]); ) D5 P* c$ V9 T/ Q! f
65 register ulong a = ntoh(k[0]); 4 s2 \ _) u0 a% Z8 c4 W1 l
66 register ulong b = ntoh(k[1]);
' ?8 B% {3 n- l8 V67 register ulong c = ntoh(k[2]); ; f; p1 z3 r: n) {' A. m
68 register ulong d = ntoh(k[3]);
1 J& h/ N: |9 o" E1 f69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ ( s7 n' f4 ?3 y" g& T) J2 r" m+ P
70 register int round = _round; . P0 o' F' s; \5 a S7 v
71 register ulong sum = 0; 0 i* H5 Z, ?$ ^; W9 e. i
72 ! N K. K) I& k1 ]: c
73 if (round == 32)
, [2 F& w$ e( N$ J74 sum = 0xC6EF3720; /* delta << 5*/
( n w+ C6 a1 r6 W6 s6 h9 x75 else if (round == 16)
& J, q3 s. ]1 K, y& ^( s9 ^76 sum = 0xE3779B90; /* delta << 4*/
: V4 m7 l* v' m$ D/ W& j77 else 6 {3 C0 C6 ?% `. }/ L
78 sum = delta << static_cast<int>(logbase(2, round)); * S- o5 p9 ?8 x G' Q( c2 l1 z6 V
79
, u% N+ Z8 N6 r7 G# r& d+ L80 while (round--) { /* basic cycle start */
7 x* Y4 Z/ N2 H. k. B- L3 r t81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); 8 M* w2 M! Y& K. E& L
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
3 B6 \9 V- q# K83 sum -= delta;
3 t, E0 W, \6 n0 Z84 } /* end cycle */ - Y" J# I1 I8 w+ b' F
85 out[0] = ntoh(y); " p% h- r8 h: n$ a0 s" g# r2 l* x
86 out[1] = ntoh(z); 5 W$ E1 x+ C1 I# k
87 }
& [9 K: v+ {. X1 X# z: [
, D; J% L9 D( S# o+ i' M需要说明的是TEA的构造函数:
& C* m8 j; t* ^6 l4 B( G9 @' \TEA(const byte *key, int round = 32, bool isNetByte = false); 7 j& b( l; s7 B3 Z& Y
1.key - 加密或解密用的128-bit(16byte)密钥。
2 F1 M2 D% }* V+ E; w2.round - 加密或解密的轮数,常用的有64,32,16。
/ X+ w8 c. g$ C. j3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
2 `' \2 m8 u3 i" E; r4 O9 r+ S9 _* f
- G. s5 R W1 K最后当然少不了测试代码: |
|