|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" 0 O; d0 I0 D4 r: F3 X, d7 E1 N% c; |
2 #include <cstring> //for memcpy,memset ! O4 X3 r: N* g' D' ]2 e8 N
3
& S# r) t. y& | f 4 using namespace std; # A0 t* Z8 }& r3 q
5 6 w- o+ Q1 q5 }/ |( j; N. H/ |
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) ! I+ i4 ?* R3 \" L. Y6 H
7 :_round(round)
% C$ G3 L; ~" U9 Y D 8 ,_isNetByte(isNetByte) { 2 G. m& J2 P* i Q1 C1 s
9 if (key != 0)
" z: e7 O! a. Z$ d10 memcpy(_key, key, 16);
1 {* F' x$ r( A8 h k11 else
8 `4 k# u7 j9 u- w8 y12 memset(_key, 0, 16); $ b h. G1 o `' L
13 }
) _6 Q3 R( \: c9 P* V7 f14
" Q2 ~3 p0 i. @* ?6 @15 TEA::TEA(const TEA &rhs) * i& a/ Z0 m/ U" L$ Q( p: j
16 :_round(rhs._round)
/ O/ m* u. V% @7 I( F( \1 E5 z17 ,_isNetByte(rhs._isNetByte) {
' x7 g, o8 R! [/ C& `18 memcpy(_key, rhs._key, 16);
$ I4 h: Y" ]7 j2 U2 ]19 } 8 k+ X, u% G, u; {) l* ~
20
' {% Y1 @" Y9 T- f21 TEA& TEA::operator=(const TEA &rhs) {
4 @% j; _! W4 `4 T! |22 if (&rhs != this) { 7 w% p# j# X- q& {( I
23 _round = rhs._round;
$ |% J9 B4 H/ s! F8 T0 y" N' z9 m, r24 _isNetByte = rhs._isNetByte;
& c9 b2 _) y$ ~( B1 F$ F1 ~25 memcpy(_key, rhs._key, 16); ! x8 J* {. L, j) w. a
26 } - B$ \/ G( v0 }- k2 j
27 return *this; + w8 I2 j0 |7 P: ~6 c
28 } & @, h2 p3 s; x _6 A, e" h
29
& @& s) q/ c. U5 ]- S! D' a0 }; d8 s30 void TEA::encrypt(const byte *in, byte *out) {
/ o7 y) p5 z% X# `9 V: i31 encrypt((const ulong*)in, (ulong*)out);
- t, p8 l3 r: B- o/ A32 }
1 d( L& \, `( }0 _" \- ^ R" j' Z33 - `4 t, v# V# G2 _- S' n2 G3 R4 [
34 void TEA::decrypt(const byte *in, byte *out) { ! z* G0 J& Z2 b n
35 decrypt((const ulong*)in, (ulong*)out);
4 L: z1 U7 M* J8 m36 }
6 a" n4 f* n4 I8 c4 J37 6 r/ Q1 A. [2 I$ P( ?
38 void TEA::encrypt(const ulong *in, ulong *out) { ( d+ q. ~% z) @; A, M k4 P$ X
39 2 Y( v* f5 r- R" g: `! k/ W9 ?( X
40 ulong *k = (ulong*)_key; 9 W0 e7 S/ z/ w+ c& K
41 register ulong y = ntoh(in[0]); ) x& U- Q: w, e( }/ V5 ]
42 register ulong z = ntoh(in[1]);
Y* I9 A1 S* v43 register ulong a = ntoh(k[0]);
! N% K' m* ^) G9 n% Y+ u44 register ulong b = ntoh(k[1]);
4 [% C' f e5 X: B45 register ulong c = ntoh(k[2]); 9 _, I; M f( x, l# Y
46 register ulong d = ntoh(k[3]);
; ]0 x; Q7 J& f$ u3 [- o* T47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ . a3 p& |5 D! ?
48 register int round = _round; 8 n: d8 ^! M6 x& ~
49 register ulong sum = 0;
6 N. O% Y9 S! k2 e( a50
# l- z+ s& G; ?+ N51 while (round--) { /* basic cycle start */ ) ]7 v% T' n2 o
52 sum += delta;
6 I& ~, }) c: K+ W: u& G2 y53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
$ s1 Z5 ^( |& o. b: O, {54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); " S+ B0 @' |5 m$ c( I! }8 S& L
55 } /* end cycle */ $ N) N6 j" W; { z4 ~# \
56 out[0] = ntoh(y);
# X, o7 t5 p9 q: c0 j6 h" E8 C57 out[1] = ntoh(z);
' ~. L4 C9 x( E0 E1 _" h/ v58 } 9 h* l: ?. E$ g' B- X; n
59 3 k! x! ^1 y- H3 u( d
60 void TEA::decrypt(const ulong *in, ulong *out) {
" l3 T9 m- d6 k, O0 }+ G+ ^61
6 C& [9 ?) [/ W0 E62 ulong *k = (ulong*)_key;
* `. r+ j1 u: Q2 S t63 register ulong y = ntoh(in[0]); 1 f* |3 v8 ]/ ^' K
64 register ulong z = ntoh(in[1]);
6 z' s* u" d7 l2 T* Y6 F4 h, P65 register ulong a = ntoh(k[0]);
4 `( m+ A' P; ]8 k. ]7 u66 register ulong b = ntoh(k[1]);
! ~5 O" ^4 Q" { I* R67 register ulong c = ntoh(k[2]);
0 d$ H; c6 \: ~7 Q K( r68 register ulong d = ntoh(k[3]);
" o6 G2 G. o. G$ U2 O, R69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 9 Y) G6 b9 Y/ ^: {' c! }
70 register int round = _round; 5 s) n3 i9 d, w# p
71 register ulong sum = 0;
, e1 Z' c* j$ o9 F0 [9 v& F, N! x72 - g# v1 {3 R( I" U$ e, c
73 if (round == 32)
) F0 t8 j; o# _( V4 T74 sum = 0xC6EF3720; /* delta << 5*/ 0 }8 p" J) X( i8 B. G3 F9 V
75 else if (round == 16) 7 d( {6 K# s3 l ~9 D+ A
76 sum = 0xE3779B90; /* delta << 4*/
" h& Q# G, O& a" \7 c77 else 0 i! s4 z6 h& r0 }9 d
78 sum = delta << static_cast<int>(logbase(2, round)); * F( w0 B% W( K$ _5 k
79 - G" g4 J0 Z( }2 A2 e) c5 z
80 while (round--) { /* basic cycle start */
+ V5 F4 }3 j. G5 j81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
4 G4 R8 P# |% H+ x. q( w. I82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
# n- f6 R) G2 {. E# G83 sum -= delta; " n& b+ g& S5 E" a
84 } /* end cycle */ 8 A4 h6 t+ s1 q. ^* j: n. \6 a4 _
85 out[0] = ntoh(y); # Z [, V- b; M; D- N" R- e
86 out[1] = ntoh(z); 0 O, d, {1 ^& \+ w8 J) \6 C) s$ s3 A
87 }
+ N6 F8 j2 |. k
9 j7 a( N: `. k需要说明的是TEA的构造函数: 6 C" d9 q7 D& c' d
TEA(const byte *key, int round = 32, bool isNetByte = false); $ m/ U- D$ [( K6 A% c6 f+ K0 E; ]4 R
1.key - 加密或解密用的128-bit(16byte)密钥。
" S& q7 h( d2 d: ]2.round - 加密或解密的轮数,常用的有64,32,16。 - s$ o9 x4 C9 ]" A4 x0 f8 ]
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! + Y' R1 U6 p/ _3 k6 f
8 N k' Y% _2 W5 @4 p最后当然少不了测试代码: |
|