|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" % W) s3 h V: c8 \
2 #include <cstring> //for memcpy,memset
; L- E% _- b7 f' J- {! ^ 3
( ^' }3 A( |; q7 p0 w: [, y 4 using namespace std;
, C1 e4 u, Q. t$ M$ _ 5
9 {# q/ {* I/ {( g9 `# o 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) ' b# V6 n0 N% R) B6 w' n
7 :_round(round) & R2 d: j' K9 I R1 t2 Z
8 ,_isNetByte(isNetByte) { 9 c% y9 ^( o5 v+ B
9 if (key != 0) & s9 |2 H O. i! O2 o+ l
10 memcpy(_key, key, 16);
; J* g7 Z! Z7 w, y5 Z/ j& V11 else
0 g, c% ^, \( t1 ~7 M12 memset(_key, 0, 16); . Y3 T+ X+ d1 e& W8 s
13 } 4 m- r9 q# y9 ] t* B6 g
14
. a( V2 g0 B" u, T$ s: m; o15 TEA::TEA(const TEA &rhs) ! @/ g0 Z, U' a/ \* Q1 Z* l
16 :_round(rhs._round) . Q9 f# g" D5 h
17 ,_isNetByte(rhs._isNetByte) {
% \" ~% O$ R: W/ @18 memcpy(_key, rhs._key, 16);
- v$ I6 v7 b" [9 A' R" m19 } 3 B% i) I* C9 s( h' @7 A# w
20 * k/ u; @( D7 M- w* o U
21 TEA& TEA::operator=(const TEA &rhs) {
& p- t0 Y4 i5 n$ N2 a5 o, x0 p! \22 if (&rhs != this) {
/ @. x. Y' S7 ^4 `7 }' O23 _round = rhs._round;
! X# X$ W3 n- y; `# E/ G24 _isNetByte = rhs._isNetByte;
# U% n1 `& W8 b' X, l25 memcpy(_key, rhs._key, 16); 5 M- i L' R* b& U7 n$ s$ c
26 } 9 I; t5 C: ?7 r5 l- t# [
27 return *this; 8 }1 n) X0 m p1 e
28 } ! w1 I6 } `9 v0 e% E9 b
29 1 H+ f% S% L' u% M$ S
30 void TEA::encrypt(const byte *in, byte *out) {
8 u9 Q! R* G8 G1 O4 ^) ]31 encrypt((const ulong*)in, (ulong*)out); # X0 K; @) K; J9 \
32 } - b: j0 c" N; a
33 2 d% g% U4 i- G6 D
34 void TEA::decrypt(const byte *in, byte *out) {
: D( [) Y' B# K* m1 n7 [. j7 h( M& x% \35 decrypt((const ulong*)in, (ulong*)out); ! e5 k+ B7 B* \$ R: X7 J
36 } ) t9 L4 l5 F- t" s% ?
37
$ G0 j0 K3 x5 }9 k4 a. I38 void TEA::encrypt(const ulong *in, ulong *out) {
9 }4 D8 X) m: V1 \( v) G39
( N @) `4 }! c0 v) M- s! A- u& N40 ulong *k = (ulong*)_key; 4 M4 U* n- K3 I- f
41 register ulong y = ntoh(in[0]);
! J, Q) m5 |6 y7 r4 B. ^42 register ulong z = ntoh(in[1]); 1 N: Y5 z6 |) V- }
43 register ulong a = ntoh(k[0]);
" g+ n j, E& Q# ]44 register ulong b = ntoh(k[1]);
2 A+ X) }( O1 t45 register ulong c = ntoh(k[2]); , b( l1 L6 C8 a/ O$ k
46 register ulong d = ntoh(k[3]);
7 I3 L% t2 O+ }47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
: `% v q1 N/ H48 register int round = _round; 6 f' [# }, U2 }' }. t3 m
49 register ulong sum = 0; - _3 _8 P) Q' ^8 S3 n
50
* }7 k5 `4 F6 d2 l' P51 while (round--) { /* basic cycle start */ # T8 Q, m' [* g3 }# R
52 sum += delta; , ?: O) C1 r3 O, b( Y k
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); * A4 V& U4 H% n1 a: p
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); * M' B2 h7 g5 ?6 h
55 } /* end cycle */ , O9 ?: k' V1 t' e9 J
56 out[0] = ntoh(y);
K2 y' V/ N. h- `57 out[1] = ntoh(z);
( r) r( J6 F: @+ X/ `58 }
8 S% X; H2 A5 p j* n( G59
3 `. u* u8 C/ Q% e9 E60 void TEA::decrypt(const ulong *in, ulong *out) { & U+ h. p+ Z+ N5 Z9 k8 g
61
9 F- F9 V; k) Z& t9 X62 ulong *k = (ulong*)_key; ! V$ |) y! Y3 J7 _
63 register ulong y = ntoh(in[0]);
, I3 a0 ? A2 w% z. N64 register ulong z = ntoh(in[1]);
7 F6 I% A7 Y1 G: s ^+ o& T65 register ulong a = ntoh(k[0]); 5 z6 I g' y% Y# v' y
66 register ulong b = ntoh(k[1]);
+ e& B: P" i" s( ]6 \# W67 register ulong c = ntoh(k[2]); ' e; B8 N8 {; Z8 R6 L$ E
68 register ulong d = ntoh(k[3]);
% Q- _8 P/ K- ]69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
: K6 s% R2 \' i4 T W+ E70 register int round = _round; & W( t2 a: N3 X+ o2 D
71 register ulong sum = 0; : t7 A5 D- |7 I$ \: E
72 : D5 h5 j" c/ E6 W' t( p
73 if (round == 32)
5 T+ X) W* o! H6 H' \74 sum = 0xC6EF3720; /* delta << 5*/
# y( J! g: w& T7 o l2 }75 else if (round == 16) 5 W/ G+ J6 ?$ o6 V6 G. N9 Y
76 sum = 0xE3779B90; /* delta << 4*/
* ]6 O9 q0 N; u1 D77 else 7 _: P; m! a k- Z- _1 i0 _
78 sum = delta << static_cast<int>(logbase(2, round));
2 Y# C4 q. Z/ r- A79
) S* \- r- H, G; x/ i$ k80 while (round--) { /* basic cycle start */
+ Y5 x2 y+ Z8 L4 i$ G+ r9 U81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); 7 C& z+ k1 i/ E R9 c: |) h7 ~$ \
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); / Z8 G: E1 Y8 n! N3 @
83 sum -= delta; 7 ]: R6 x0 A" s
84 } /* end cycle */ * `7 Z9 ~: h2 [6 K: O8 j
85 out[0] = ntoh(y);
8 E5 x# J/ M# g( f- V) m86 out[1] = ntoh(z); - R. j" E1 C$ \
87 }
9 z5 V- Q5 Y1 U0 m" Q( U1 Z4 Q! M9 z1 D/ m, F: U
需要说明的是TEA的构造函数: , l: }0 ^3 T0 N2 a+ j# _2 ], i* q
TEA(const byte *key, int round = 32, bool isNetByte = false);
/ s) p! b, ^ L" y. w) h1.key - 加密或解密用的128-bit(16byte)密钥。 ) D* X$ L3 }' E6 a6 }+ b
2.round - 加密或解密的轮数,常用的有64,32,16。
5 T: n( x4 h: V$ v+ o0 N- Y3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! a% o' ~9 f8 S3 Z
& J0 |) c! h1 d6 f7 _" V最后当然少不了测试代码: |
|