|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" : I4 Y f$ J( I
2 #include <cstring> //for memcpy,memset ) n8 @% B& G! x. p8 n" @% F
3 , S3 l8 i8 K( @7 D( t* ?+ J+ {3 e$ A$ e( N
4 using namespace std; # n4 |+ z8 v1 z) i+ d
5 " r8 V* [5 Q+ N0 E4 o" @$ E
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
7 `4 W" ]" H: A2 A0 C- M% b( Y 7 :_round(round)
9 N! r* _& M( S& y& [8 ]# l 8 ,_isNetByte(isNetByte) {
7 W5 z9 M. t* y* H. q 9 if (key != 0) ; n) U' n) y4 S# S* R6 M8 {
10 memcpy(_key, key, 16);
( h$ e* T: X4 \" V0 H' v# e; ~7 A& B9 t11 else - i+ v; B2 r& Y% p
12 memset(_key, 0, 16); ; w) k( H9 h+ ^0 m% ~
13 }
9 K/ }) Y* K! U) V9 `1 W14
/ G" ^6 o7 h, |15 TEA::TEA(const TEA &rhs)
4 M: t& ^! W1 Y* ^; u4 q2 D16 :_round(rhs._round)
3 _- |$ M' j4 {' b17 ,_isNetByte(rhs._isNetByte) { ' Q) o5 [5 ^6 h
18 memcpy(_key, rhs._key, 16);
3 I4 T" `5 k$ J1 e19 }
8 p& R$ I6 x5 C' k20
) x) H5 O5 y; ]$ R9 ~% K4 D" e3 @5 J21 TEA& TEA::operator=(const TEA &rhs) {
1 M3 b9 |( q9 I5 ]; Y6 Z. Y) w22 if (&rhs != this) { & H5 F+ f7 w- L
23 _round = rhs._round; 5 M) ]- X/ f; H4 V
24 _isNetByte = rhs._isNetByte; 1 l2 U0 \: Y8 }$ e
25 memcpy(_key, rhs._key, 16); * q3 g4 _# r2 v: p
26 }
- A& |3 C8 f" s. {4 @27 return *this;
# p' h1 z5 e1 o, T( c: V+ i8 J28 } # t! r* M6 _! y8 Z2 j9 R
29
: z! M1 q2 p5 k8 z6 i7 C30 void TEA::encrypt(const byte *in, byte *out) {
& Q: o1 p8 Q7 m/ V! l9 @31 encrypt((const ulong*)in, (ulong*)out);
$ x* V, m& \& k3 T32 } , m" z4 u5 Z3 g1 X
33 2 {+ ? a" Z$ `# H7 r
34 void TEA::decrypt(const byte *in, byte *out) {
+ h i8 G+ r* B) n& ]$ q35 decrypt((const ulong*)in, (ulong*)out);
g* D) x1 p x7 U9 N$ r( ^36 } Z! G4 s; ~- D2 Q$ w; Y$ M, }
37
3 ^! J. y8 `# J1 ?% z/ G% o38 void TEA::encrypt(const ulong *in, ulong *out) { / c. W9 G& Z" U2 y/ H1 b% D% M
39 ' s9 C2 ^ C6 g; _ ?
40 ulong *k = (ulong*)_key; 0 R3 ]4 i% M: y- t3 a
41 register ulong y = ntoh(in[0]); 1 w2 T5 e' y; b" D" ?: V
42 register ulong z = ntoh(in[1]);
5 d1 ]/ x8 `+ M" T, e2 a6 t43 register ulong a = ntoh(k[0]);
8 k) O+ b, q; v44 register ulong b = ntoh(k[1]); U/ I9 \) Z+ x# F. C0 y
45 register ulong c = ntoh(k[2]);
* Q( S: i, ]' B46 register ulong d = ntoh(k[3]); ( y1 J( }- p j9 J: s
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
- j4 N/ o0 Q5 C. y X8 l48 register int round = _round; ) q% d2 l+ A- X4 K$ x# h* |& N9 }
49 register ulong sum = 0;
1 r- i3 z; h; O( |3 i* g' |50
9 A; c4 R+ r/ x% q) ]& s, o51 while (round--) { /* basic cycle start */ _$ F" q2 Q+ g( N; H, L b
52 sum += delta;
3 E' q) G+ |# U- F+ a53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
& {: ]4 ]' ]0 R) q- x54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
9 L8 I/ L( b5 T6 L' ]; r55 } /* end cycle */ * A" o1 w5 W# W g/ h
56 out[0] = ntoh(y); * R4 X# _' X* j* R8 g6 n1 Q/ f
57 out[1] = ntoh(z);
* `0 w6 V+ p( x58 }
( Z2 [4 c, Y5 W+ W59
0 |7 A5 b) s# I4 O60 void TEA::decrypt(const ulong *in, ulong *out) { 2 k- o# ~/ I1 s- N# t) j$ [, Z+ O
61
% a' E& Z& a- u) Y' Z" W62 ulong *k = (ulong*)_key; * K/ l( n9 r' K- [1 N6 j1 L, ]
63 register ulong y = ntoh(in[0]);
0 Y* V+ B3 l4 ~! J6 n: r- |; C( ?64 register ulong z = ntoh(in[1]);
4 g: F7 W6 |; o7 ^6 l65 register ulong a = ntoh(k[0]);
9 [( x5 Q% P2 i0 y66 register ulong b = ntoh(k[1]);
4 s* {3 k/ o: W8 t3 u( n1 }' ]67 register ulong c = ntoh(k[2]);
8 O" l; [0 O' p6 |4 L68 register ulong d = ntoh(k[3]);
( R$ T8 l# l5 f" q/ {- v69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
& N% l: t, V$ x) q; t" w6 @70 register int round = _round;
$ y( f; G M# O0 T" ^71 register ulong sum = 0; 4 x1 n7 u8 q& ]: d S
72 " t6 D0 X0 r8 a: s& i/ `6 H
73 if (round == 32) n: Z( @% e! u S4 P
74 sum = 0xC6EF3720; /* delta << 5*/
% m2 e/ ^2 }+ A* t' A# @75 else if (round == 16) ) k1 r0 e6 Z0 \8 W4 N% u% r5 f
76 sum = 0xE3779B90; /* delta << 4*/
) K+ {9 a$ L- U4 [/ m77 else
4 {/ P! X, H' ?) z78 sum = delta << static_cast<int>(logbase(2, round));
" I) N. B% P! L" T1 a$ s0 }+ t79 & V" }/ l. p: s, K3 R1 e5 y: {8 q0 Q
80 while (round--) { /* basic cycle start */
, O0 U9 X, }' r2 v6 [3 ^$ C81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
/ D6 j1 [4 ?+ F82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); 0 Z5 Y( ~' ~0 ?3 u$ r, f! Q! P
83 sum -= delta;
% u. d& X" t( u' {3 c( H84 } /* end cycle */
: V- W% M$ t( v* H4 R" a* M8 p85 out[0] = ntoh(y);
; |5 h6 ^) ^* d86 out[1] = ntoh(z);
' {$ M& o- ?4 y! C I! B8 z87 }8 s' w( d7 N. K3 S
. J+ m$ `/ i+ X
需要说明的是TEA的构造函数:
2 a7 z& o8 y% h r6 wTEA(const byte *key, int round = 32, bool isNetByte = false); 0 ~: x) y+ e |! e
1.key - 加密或解密用的128-bit(16byte)密钥。
0 _/ x/ x* t0 ~2.round - 加密或解密的轮数,常用的有64,32,16。 6 V3 f$ O: ?" n( Q& E. h3 Z
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
! m" I; U& O9 h! k
% q# k% H% y2 d4 O& R! Q4 [4 Q! N) D最后当然少不了测试代码: |
|