|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
5 [4 v7 E) m9 ^. I2 h 2 #include <cstring> //for memcpy,memset
! b2 x H5 D- T2 z0 { 3 ' [$ u4 S9 g) x4 f& ^4 [$ L
4 using namespace std;
& G! A7 M8 |4 W 5 # D3 T2 ^* W3 i$ m1 p: O1 p# Y
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
; t# ?$ Z1 P; S( i6 a6 a+ E: s 7 :_round(round)
* r9 x/ n. F: } 8 ,_isNetByte(isNetByte) { 9 z4 \7 ?3 d. J8 `! \) ]
9 if (key != 0) - Z& b( u6 K2 R5 H
10 memcpy(_key, key, 16); r+ L2 P: Q0 l
11 else
0 B# l5 q2 Q1 g* ]5 w1 l. S1 y12 memset(_key, 0, 16);
5 p' H7 E) X; Z( ~; ?' Y13 }
2 q8 @) J# ]6 D" T( k14 2 {- ~. P- S. n2 o% n3 \. }$ _ p V6 n
15 TEA::TEA(const TEA &rhs) 5 G; n$ P/ C0 [/ {* u( E& z
16 :_round(rhs._round) + Y0 Z. V0 V% \( q( D. E7 C6 L
17 ,_isNetByte(rhs._isNetByte) {
! K3 A3 k1 [. M) z7 \" d+ v0 d18 memcpy(_key, rhs._key, 16); 9 e" V0 E# t: i
19 } 8 u7 r( a @; V3 n
20 - ? l( P* r4 ^3 J
21 TEA& TEA::operator=(const TEA &rhs) {
1 m- j; y( n# w5 ]( O X* {( _5 U; g22 if (&rhs != this) { 1 D6 W. p3 j ~2 j
23 _round = rhs._round; - w6 a6 \9 o; Z2 k
24 _isNetByte = rhs._isNetByte;
: |& H7 N/ N m2 K, E3 \25 memcpy(_key, rhs._key, 16);
. F' l7 _6 r+ H1 `26 }
7 w+ P* U7 M- B' t" _+ n6 P$ H2 j27 return *this; % `8 `4 o' {' t% Y$ u) B- b
28 } : E* E% Q: x1 j
29 % E, Z& S4 k- a1 y. ^9 M, s/ K
30 void TEA::encrypt(const byte *in, byte *out) { ! t" Y9 j5 y0 t- h3 S) X: v
31 encrypt((const ulong*)in, (ulong*)out);
9 [. G. W" s1 f" l( ]8 o: `, \32 } # U/ ]8 Q+ b& O8 x9 t* k
33
# B' R; k8 C4 w; M% A34 void TEA::decrypt(const byte *in, byte *out) { ' N# E- S1 B/ y
35 decrypt((const ulong*)in, (ulong*)out); ( z1 O Y/ i2 t. A+ u% r
36 } % U) c/ `# E* U( ]" \# u; Q3 V
37 / z9 {/ K M. E; v% `7 o. H
38 void TEA::encrypt(const ulong *in, ulong *out) { * m/ C! B( @# }( n5 P
39
* D6 j) ~6 C$ `40 ulong *k = (ulong*)_key;
8 Q, I5 W4 d @4 _0 s5 T& l# ?41 register ulong y = ntoh(in[0]);
9 p4 k3 ~. l5 u1 [1 ~42 register ulong z = ntoh(in[1]);
, c; i- @% q1 n* H! |. W( j9 }' q7 U43 register ulong a = ntoh(k[0]);
, g. j/ @# ^3 J) f1 a L44 register ulong b = ntoh(k[1]);
, H/ ]( [ } l1 h* g. P45 register ulong c = ntoh(k[2]); . F/ W& P* t: ?
46 register ulong d = ntoh(k[3]);
* i) l, z' T7 p1 h: o; z: F- E! o" g47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
3 b( r T; X, g: E48 register int round = _round;
' g( s% T* `* ]: M& p) R. Z. E! L49 register ulong sum = 0;
" U- y) m4 L0 I' r+ \/ n) K50 " ^- M* X7 C7 G. C
51 while (round--) { /* basic cycle start */
& P4 L- W8 m5 K" G: K% D52 sum += delta;
/ ^3 _: m4 S2 k" m" Z53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); . \ `$ E- H" C0 {4 ^( g# y2 ]1 W
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); / i. w6 E; b0 g" B
55 } /* end cycle */ ( S# V1 _ q) a: [& \( r
56 out[0] = ntoh(y); + W# _9 a/ D* M; ]1 ]9 Z
57 out[1] = ntoh(z); , k& K4 n0 }0 V4 R7 e/ ~. x" s6 v
58 }
0 e$ M- V! j/ U; M, }$ r: I59
& S3 W! V# K% m* v9 u5 J5 N60 void TEA::decrypt(const ulong *in, ulong *out) {
4 t" r4 \; X; i* a `0 K61 - H1 t) }9 d f5 `2 A9 k( i
62 ulong *k = (ulong*)_key;
! U. m+ H" X9 H0 ~3 ~3 r63 register ulong y = ntoh(in[0]);
" ]- c7 I2 }# y1 k: Z64 register ulong z = ntoh(in[1]); 3 [1 b& A4 F- ~$ M+ h% _6 ?2 G
65 register ulong a = ntoh(k[0]);
- _. V: C0 w6 V3 I) A" I# J66 register ulong b = ntoh(k[1]); ; U0 O1 a5 K; S) X2 ?) \# m
67 register ulong c = ntoh(k[2]);
6 L) J& x: h* |# ]. Z: o68 register ulong d = ntoh(k[3]);
: m5 k9 Y( Q- ]4 Z! A' b: `! ?69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
$ e v8 a @. @. Z70 register int round = _round; 3 {+ l" N3 O; r7 Q ~" V1 C
71 register ulong sum = 0;
" K( n1 C* e; M3 }8 o72
5 l( X5 x% n" T73 if (round == 32)
7 y) k1 A/ n. B Q" V. N) Q74 sum = 0xC6EF3720; /* delta << 5*/
( H, v$ R% v4 B' z3 D75 else if (round == 16) ; q1 Q, p; S$ t
76 sum = 0xE3779B90; /* delta << 4*/ ; ?2 G" L& j' N+ b" Q
77 else 2 p) @9 Z3 P G( X6 o; n" x
78 sum = delta << static_cast<int>(logbase(2, round)); . A) x. e, F9 q1 o8 A' \. J! t
79 2 R& v! U3 q7 s
80 while (round--) { /* basic cycle start */
& [+ D* ?8 b( o( W* Y6 v# ~' ^81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
* [2 c8 v# ?; L. B+ q82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); $ v4 O* G7 ~) w( b5 K% w7 B v" s
83 sum -= delta; 2 V# Z# _4 Y3 `/ R% s+ k; R7 t
84 } /* end cycle */ ! {$ C9 o! J. f7 x2 K" Z/ ]
85 out[0] = ntoh(y); 1 P8 b& V6 v( F* g$ w
86 out[1] = ntoh(z); . k; f2 U, \; T5 n1 v0 x& p" i
87 }
0 p* Q$ |, v: v
( l6 L5 E X" I! Q4 s需要说明的是TEA的构造函数:
; d7 O$ [& @8 YTEA(const byte *key, int round = 32, bool isNetByte = false); K8 b" N" W7 n+ |: \
1.key - 加密或解密用的128-bit(16byte)密钥。
; x$ s) f2 a' q. N" z2 g: d2.round - 加密或解密的轮数,常用的有64,32,16。
8 q3 Y$ ?$ ?9 p7 f- t3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
1 Z0 Q% {& A& t0 d n0 R5 u3 b/ K# ^: J$ _/ L
最后当然少不了测试代码: |
|