|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" 5 ~% c# \# i7 Z! v$ g
2 #include <cstring> //for memcpy,memset
% W0 i! i g% f7 a 3 0 i+ D( L6 @+ N, I( a) u
4 using namespace std;
3 o1 z2 W. T7 W& y8 o 5
2 }: z a) { _ 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
8 o2 G4 _' U, G1 i+ G$ ^ 7 :_round(round) # ^; b, f/ P, V
8 ,_isNetByte(isNetByte) { % P( u, G+ s* Q! G
9 if (key != 0)
" h. ]+ z+ @: {) c' R) W5 ]$ J3 i/ c10 memcpy(_key, key, 16);
; O8 r! _; `2 E$ O4 Q! e11 else : x7 q. \, R1 ^+ D* X; @# q
12 memset(_key, 0, 16);
3 V" S% h0 d* f6 y" y( k13 }
; b! i0 p. f$ b+ _14 ! K0 u+ @8 p8 \* ?0 J
15 TEA::TEA(const TEA &rhs) ' z1 u% C/ Z1 g/ M
16 :_round(rhs._round) 5 K9 g( f+ O5 c+ E. I
17 ,_isNetByte(rhs._isNetByte) { + `1 P6 d3 G! }/ q4 k- _/ Z
18 memcpy(_key, rhs._key, 16); & i1 {- b) t; [5 G8 R
19 }
. C- k u1 ^( N" k! m20
3 r9 o* G' U$ [% B; L9 K3 Z21 TEA& TEA::operator=(const TEA &rhs) { / M. R/ i8 P7 E+ Y0 l3 K0 O
22 if (&rhs != this) {
3 w; y6 _5 F+ r1 J5 {3 D' o6 n23 _round = rhs._round; + X1 C& b7 k, H, m
24 _isNetByte = rhs._isNetByte;
* M, }; t8 n: Q, f$ \25 memcpy(_key, rhs._key, 16);
; f4 u6 ]' Q# U" {. g4 ?( ^! }26 } & m3 |) n! _9 u
27 return *this; $ J9 C+ N) r3 {1 G: v' N
28 } . {/ L5 c. {+ [6 q+ l
29 9 z4 c) I& ?; J4 N$ O4 l
30 void TEA::encrypt(const byte *in, byte *out) { @7 C& T$ O, \ V$ w
31 encrypt((const ulong*)in, (ulong*)out);
8 Y) }6 ^4 T$ m) M0 d: {7 X9 N% F32 }
+ h* X1 @- W% I+ b% J$ C% n% K. @, a33
* g# R/ h8 o$ W3 J( t1 B34 void TEA::decrypt(const byte *in, byte *out) { $ b! {+ N9 {, {# O. C
35 decrypt((const ulong*)in, (ulong*)out); * R7 Y* Z) E/ w. ?$ _; g, X+ u! j
36 }
' Y- K/ j: s2 p2 h! y5 L37
: L' i$ B/ x4 l/ b( ]! a38 void TEA::encrypt(const ulong *in, ulong *out) { ( B; U m- {( Z/ Z+ v3 T4 @
39 4 V4 H, L! F$ _5 h) B2 K
40 ulong *k = (ulong*)_key; ) `; s) B* W3 r; r! R" A' k
41 register ulong y = ntoh(in[0]);
, \' G3 N4 y, k0 c3 n42 register ulong z = ntoh(in[1]); ; `7 K, y* M# `
43 register ulong a = ntoh(k[0]);
7 j, |* @1 v6 R7 _: Y44 register ulong b = ntoh(k[1]); ! o4 ]& q. }. z7 v1 l4 i
45 register ulong c = ntoh(k[2]); 9 w- h6 ~! c, i; F: V( F* y* T
46 register ulong d = ntoh(k[3]); @: e1 b3 i6 G. L
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ # o" x& L! r4 T0 L$ `
48 register int round = _round;
0 W! j9 U1 D, t: X) C+ D% E$ S49 register ulong sum = 0;
$ ?7 Q! e* o d3 `& W50
$ i7 c c! L _! S51 while (round--) { /* basic cycle start */ ( P; e; [0 c/ F: ?1 A
52 sum += delta;
6 t( f& w6 R4 Y+ @" J9 p3 g4 x7 w53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); ; e$ v! t" A, L, _) U* c* u3 d1 D
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); 0 p' e! f0 M W2 g
55 } /* end cycle */
/ r( H# T. t6 E9 k; h( `* b56 out[0] = ntoh(y); * H0 E( N6 c* ?9 Z/ t; e
57 out[1] = ntoh(z); , U: U! k( G6 y$ c! O4 E. p
58 } ' F$ `; I" G& H& Q' |) w
59 # u( O2 Z! \( @0 v* r( R% i2 P
60 void TEA::decrypt(const ulong *in, ulong *out) { ) ^+ y6 p" R$ f" ^9 b* k( h
61 # Y2 h5 I; O5 a0 f8 Q
62 ulong *k = (ulong*)_key; : h9 [, {8 O1 {$ X, b, h/ M, D
63 register ulong y = ntoh(in[0]); $ A0 o4 a# t7 n
64 register ulong z = ntoh(in[1]); 4 B# _0 Z" @% y
65 register ulong a = ntoh(k[0]); " a2 x3 @; _; d6 w4 B
66 register ulong b = ntoh(k[1]); * L$ h8 o) [" C' ?# X# y7 u
67 register ulong c = ntoh(k[2]);
1 Y) E' o/ k0 d" [68 register ulong d = ntoh(k[3]);
6 p/ N) _0 a# F69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
2 f& W% ?; X |70 register int round = _round;
# Y4 r# i( }9 g2 |- S0 | I71 register ulong sum = 0; 1 U% C' ~& a A& f. h$ V9 M% q
72 3 k* P9 x2 I8 f( F: K. g4 G0 E
73 if (round == 32)
( a4 k# N' T9 H- L) T8 U# @74 sum = 0xC6EF3720; /* delta << 5*/ ( V) G% X7 u# }7 k
75 else if (round == 16) $ K* b* h% i3 @8 K
76 sum = 0xE3779B90; /* delta << 4*/
3 @7 ^: `6 \( j77 else
+ a [) k# O5 H! W" }& d78 sum = delta << static_cast<int>(logbase(2, round));
! F( }; |" C" ~( J2 x! R4 T+ Y7 N79 * z C2 Z& x" B( K8 @, V- s6 i+ w
80 while (round--) { /* basic cycle start */ : z& _3 \" S$ E$ u; M- r1 b
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); " m: W; v( K- B' d0 U! X7 W
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
# N4 r% C* ^) {9 x; V3 D1 _83 sum -= delta;
& Q, h& m/ Z9 C84 } /* end cycle */ 8 y& }2 w) b6 R$ X/ J. k# ^ K
85 out[0] = ntoh(y); * E+ `4 u2 [6 y/ V8 v, U1 B2 @
86 out[1] = ntoh(z); - u1 y% K: P0 \0 x" J( _
87 }; Y9 c1 ]/ V8 D) v; q
- D, I o5 M# h9 e需要说明的是TEA的构造函数: 4 o% P$ h4 G( h$ b, y. {
TEA(const byte *key, int round = 32, bool isNetByte = false);
6 @8 G7 _! c( ]1.key - 加密或解密用的128-bit(16byte)密钥。 * p7 I, k/ S& K
2.round - 加密或解密的轮数,常用的有64,32,16。 ( X$ g7 O( m$ ~: ^) q7 U
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! : V5 T) T- t; J- Z4 A6 @' ?& I
5 ^; G+ _1 n8 O; I3 R5 H
最后当然少不了测试代码: |
|