|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" % b' p0 u' ?; t a
2 #include <cstring> //for memcpy,memset
r" u9 U0 V7 u/ |: {, V9 \ 3
8 z8 m( ^; h2 | 4 using namespace std;
" v4 o3 w( E' s1 Q4 s7 O; m0 I 5
) O& o1 Q6 l& Y: ?0 ]5 K+ [1 M 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) 9 B1 r) z& _! _8 i+ K' E8 O* Q& N
7 :_round(round)
% q; A0 l7 ~% Q* q 8 ,_isNetByte(isNetByte) { 0 P( J( T! R; y; K+ r
9 if (key != 0) ) h/ v7 Y, J6 v' {
10 memcpy(_key, key, 16); $ V$ L2 B6 R, n
11 else
) n% q7 H, t0 n% d* t12 memset(_key, 0, 16);
9 h1 \3 Y% T+ y2 O1 E) f13 }
5 t, b$ ^; Y* } S3 @5 n( y14 6 \" \* y+ H: V9 \& T3 x$ D7 B
15 TEA::TEA(const TEA &rhs)
, ~4 w" S+ r8 u% L16 :_round(rhs._round)
& W/ P5 e3 a( R) [3 c0 x17 ,_isNetByte(rhs._isNetByte) {
! K+ S/ Z# C3 K' e& o/ T6 ]. t5 n9 b- b18 memcpy(_key, rhs._key, 16);
8 k; a' q7 |' o( g( F8 k3 d5 h# n+ N19 }
. Q+ h1 N# Z$ t20
. |4 {8 |0 B. I/ [21 TEA& TEA::operator=(const TEA &rhs) { 4 e ~5 J( I# Y$ q; X, u
22 if (&rhs != this) {
4 r# ?! ^. P8 ]23 _round = rhs._round;
0 C) m6 `3 p3 i7 S3 ^0 @24 _isNetByte = rhs._isNetByte;
+ a K. Y1 a+ u5 N# d2 q25 memcpy(_key, rhs._key, 16); # |. P4 x! Y1 G6 A; Z/ K
26 }
% B/ @: q) B$ |( E27 return *this;
5 M8 i5 E' h+ t5 F$ @' x9 B0 a3 W28 }
4 J2 C# u3 e! j" B: o+ ]29 9 V% l( n4 X& @. S# ?& ~6 g
30 void TEA::encrypt(const byte *in, byte *out) {
) z m0 s, p) g( n, [ E4 X31 encrypt((const ulong*)in, (ulong*)out); d* q1 W6 i3 H" J# g; f& l
32 }
' k0 j- p9 ~ T2 s# V9 h3 q33 2 D9 c5 R! _. t9 `) |2 Y1 v
34 void TEA::decrypt(const byte *in, byte *out) { 2 ?4 E5 l( s# a) f: N H
35 decrypt((const ulong*)in, (ulong*)out); 5 W J M6 l9 R- d3 f; z
36 } ; l* ^ q# a2 t6 T# M$ [4 m% j3 j
37 ' Y' U& t, O9 f5 S
38 void TEA::encrypt(const ulong *in, ulong *out) {
Z, @! `4 J {& c$ A; A39
7 V$ e- J: V: `40 ulong *k = (ulong*)_key;
p; t0 u& A8 R* M7 o8 _41 register ulong y = ntoh(in[0]);
4 r$ s& p0 {) G42 register ulong z = ntoh(in[1]);
% h6 E9 i" j( R* s& y1 v5 A# C43 register ulong a = ntoh(k[0]); + |: i2 [! ^9 Q4 D# p, d
44 register ulong b = ntoh(k[1]);
0 e, V& X) v8 S& F( u9 c4 v- _7 S45 register ulong c = ntoh(k[2]);
- m& P+ X$ ?! f8 _1 C8 j46 register ulong d = ntoh(k[3]); + b' i2 |5 z* |/ Y' O2 o2 e
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 4 X) E- X- w7 O3 Q4 J/ f
48 register int round = _round; 8 r6 A9 Y( T# n% G' I6 j8 x
49 register ulong sum = 0;
& M) f2 ~0 d1 _50 : ]. j& @3 P$ Y8 A8 F
51 while (round--) { /* basic cycle start */ 4 t2 _5 l& t: _3 n
52 sum += delta;
% f1 u" ~; p# K1 h, I! Z( O- p) R7 Z53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); 5 ^& p/ z; \7 W V, j0 J$ G( i: Y4 {
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); " a0 T5 w' i( Y+ U) e" Z
55 } /* end cycle */ ( k; H \5 w# V
56 out[0] = ntoh(y); ; S. Y: A! I# c
57 out[1] = ntoh(z);
9 r* ^/ V' X- j7 ?8 ]; S58 } : ?4 u6 y" q3 o
59 & b4 }0 V' \. d7 ]9 V: d. ]% c1 J7 a
60 void TEA::decrypt(const ulong *in, ulong *out) { . v; {7 c. K- h, \' v2 r
61
2 y$ u" e3 }1 K# }62 ulong *k = (ulong*)_key;
. O U" Y; A) A8 @7 ?63 register ulong y = ntoh(in[0]); 2 |& [5 v1 X) J0 h# e: b
64 register ulong z = ntoh(in[1]);
0 p9 G% i0 A; Y& B; I; k65 register ulong a = ntoh(k[0]);
2 |: A' t4 I" x/ I2 ~! S66 register ulong b = ntoh(k[1]);
5 Q; n+ M _! x% f: }67 register ulong c = ntoh(k[2]);
1 V! t* ], E) x) j# G68 register ulong d = ntoh(k[3]); # s" r3 `# m& P: F
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 4 B4 d3 ?- e& X
70 register int round = _round; / w7 S5 E) ?) \8 K- @' p
71 register ulong sum = 0;
9 ?! F4 y2 I0 o1 K72 ; ^8 ` R- n1 h6 m
73 if (round == 32)
0 ]. Z$ T5 N/ Q3 B7 P74 sum = 0xC6EF3720; /* delta << 5*/
Y" |- n9 C6 o1 }75 else if (round == 16)
3 _1 o8 v' x2 w& M) e76 sum = 0xE3779B90; /* delta << 4*/
& f9 J- }' w! G8 b& H$ T# {' h77 else
2 E( B f' f& u78 sum = delta << static_cast<int>(logbase(2, round));
" A% t2 L Z* r: ~6 X! w) Y$ Q79
* O6 `) `+ k3 w$ l7 A2 O80 while (round--) { /* basic cycle start */ ! l- i+ C1 t( b* t
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); ) J/ e; O: `& e- _) A
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
; ?8 C/ G- o9 A" U, G/ {) h1 {* c83 sum -= delta; + M& _/ h* J1 y) u5 e& l# \/ G
84 } /* end cycle */ ) t Q4 K8 c2 S
85 out[0] = ntoh(y);
" U; B1 x! B4 n' `2 M# u( J/ K86 out[1] = ntoh(z);
v! z2 y, D1 ~87 }
+ i1 I* q0 I/ D- i- l! ?- ]) s- d/ J% X9 | j7 b
需要说明的是TEA的构造函数: 9 V1 [& u/ u' C2 P, q' L
TEA(const byte *key, int round = 32, bool isNetByte = false); ; K$ h) @! P: H6 C
1.key - 加密或解密用的128-bit(16byte)密钥。 3 _/ w( L1 I r8 }/ N. u
2.round - 加密或解密的轮数,常用的有64,32,16。
3 F0 c8 x7 o" i' J. K+ _; V0 S& i3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! $ r1 V. O, B5 n3 j9 w
: E! j1 p7 T V4 G: U$ t7 Q4 }/ L- k最后当然少不了测试代码: |
|