|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
9 M# o/ n9 H6 w$ @6 U 2 #include <cstring> //for memcpy,memset
. Z* Y3 z8 w- T 3
0 _' M6 N, l( G$ N- V 4 using namespace std; 1 i6 b: n* i; v9 I6 M
5
3 z" M6 Z1 }* |" K 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) 8 Z8 I5 y. J2 J2 h+ Q' u
7 :_round(round) V8 n& y: G8 s& u: O5 y+ M8 M& w
8 ,_isNetByte(isNetByte) { , [& B' H7 D; X. L
9 if (key != 0)
: i9 p& d+ x3 x- K$ q10 memcpy(_key, key, 16); 4 i* `+ T3 {6 \3 f, s
11 else
% O4 i: {$ I; r& `3 X9 ]% e5 b12 memset(_key, 0, 16);
- E. P8 V- r+ T! y13 } 5 O/ N, f3 L1 H2 w1 o9 S* m
14
# A. X% k0 E/ U9 J/ t( ~3 S15 TEA::TEA(const TEA &rhs) ; `9 ]: W4 m+ h8 S! J4 G1 F
16 :_round(rhs._round) - F" Z4 r4 G, b3 i/ b
17 ,_isNetByte(rhs._isNetByte) { + c4 e0 c5 N3 ^6 n0 v8 | B, r/ c! R
18 memcpy(_key, rhs._key, 16);
& }1 ]7 m( U& y \/ B7 x$ f* O19 } % b& E. [1 J u
20
4 S l3 ?5 f1 |5 K! J, o21 TEA& TEA::operator=(const TEA &rhs) { 2 g2 P& Q& N1 B
22 if (&rhs != this) { & C! o S$ Q+ u4 S4 M
23 _round = rhs._round;
6 a' |% i, o: \7 w! S: A- Q24 _isNetByte = rhs._isNetByte; ( x: ]$ K! T/ e1 i* u
25 memcpy(_key, rhs._key, 16);
( P3 m# U! C3 e$ P$ f+ g26 } " b! G4 I' H+ f% L
27 return *this;
, ~- v3 L7 O! f9 C9 M$ h+ h28 } " E7 y8 ~' V( j
29
# X# }. H( Q' @2 T- B; o30 void TEA::encrypt(const byte *in, byte *out) {
: ]/ U. t. F5 n; g31 encrypt((const ulong*)in, (ulong*)out); 5 ^4 v: q) B. s; P8 X. _. g( w
32 }
! ^/ p4 y! O& C" I$ ]1 u33 / Z+ K+ U5 D; D; H
34 void TEA::decrypt(const byte *in, byte *out) { ' R9 f% @3 b+ i3 t8 e0 v7 A
35 decrypt((const ulong*)in, (ulong*)out);
4 [! O9 |' @. e36 } 3 \' @5 p z, `6 b' N
37
1 Z( h7 x5 m5 {! g& R) I0 ^2 a38 void TEA::encrypt(const ulong *in, ulong *out) {
9 V* }, A$ G& J- `/ Q( ^39 - `9 k' N" P! ^1 s4 }$ ]. k3 g
40 ulong *k = (ulong*)_key; 8 y5 k) K4 V( l/ P$ l0 }% }, l/ H
41 register ulong y = ntoh(in[0]); , ~( f" W/ Z6 I0 w9 `, n# r0 X3 W
42 register ulong z = ntoh(in[1]);
1 i4 M1 t& v4 _* P43 register ulong a = ntoh(k[0]); 3 M+ t! ~, A& i% V/ Y
44 register ulong b = ntoh(k[1]); / W! y" z) h- t2 w
45 register ulong c = ntoh(k[2]);
5 k5 a( e* I" y" z( f46 register ulong d = ntoh(k[3]); " G8 r# {( Z9 q- B) l$ t
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
) M! u+ F. `6 k48 register int round = _round; # P M/ E d- j4 p, S
49 register ulong sum = 0;
; i0 Q8 a s, A50
* ]3 N: \8 D& ]8 u% i! N51 while (round--) { /* basic cycle start */ 7 n$ d9 j9 K( Z9 U; {
52 sum += delta; 1 G1 P% e5 b# Q$ ^5 P
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
. M6 V1 W2 ~8 L/ O( |- O' ]) |3 n54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); 9 S/ J5 l5 c& L& E8 j
55 } /* end cycle */ ! v8 g' @' e) @
56 out[0] = ntoh(y);
# T. Y* Y$ m0 {9 D! p57 out[1] = ntoh(z); 5 `" k+ j- B7 F
58 }
; x; V5 B4 `, x* x5 }' q59
4 W( A$ V( o) m/ ?60 void TEA::decrypt(const ulong *in, ulong *out) { ! ^# E0 `7 J+ Z9 ]" p
61
0 W+ C- D8 F$ C* O62 ulong *k = (ulong*)_key;
- z/ W$ o& \) ` s63 register ulong y = ntoh(in[0]);
/ H% T; c: r6 w, d! r- [64 register ulong z = ntoh(in[1]); 6 d# R" S( W3 v9 }/ K4 @; ?
65 register ulong a = ntoh(k[0]); t* \" c. Z R% v: o# h; K2 a
66 register ulong b = ntoh(k[1]);
) f' y9 c" x; N5 C6 e67 register ulong c = ntoh(k[2]);
7 U% C# U# ?( |1 a1 W: J68 register ulong d = ntoh(k[3]);
9 _, Z; ?% [# x* F U& H69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
3 ]- h. ` U" D. n+ H" c/ m70 register int round = _round;
: I" h; |2 m1 W% S. K71 register ulong sum = 0; ; k1 y8 @) G& [7 I
72
) x/ i+ M+ z% _+ _* L73 if (round == 32)
! I" g0 @0 N* D7 G/ g* ?- T4 v74 sum = 0xC6EF3720; /* delta << 5*/
1 d4 i8 ~" U1 ^9 _# D7 Q' q75 else if (round == 16) / S6 Y; n8 t% K. l3 z7 I
76 sum = 0xE3779B90; /* delta << 4*/
7 v" [6 E5 s+ W4 J/ u Q! @77 else " ~1 H4 A& o9 Z' C& w
78 sum = delta << static_cast<int>(logbase(2, round)); . o1 |- ?" M4 P( s! u" F+ z5 O$ v
79
3 X# B& d+ C5 O* V6 E" G2 b/ L80 while (round--) { /* basic cycle start */
8 s7 \% p# b4 } N5 g* [; [" z! T81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
1 L, D. D, Q5 E82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); 7 e6 z2 v7 L4 a4 \
83 sum -= delta;
9 R% m. u/ p; _% k84 } /* end cycle */ $ l8 z+ A! b. R& O; U4 C
85 out[0] = ntoh(y);
9 @) I. U& t& z1 o, u86 out[1] = ntoh(z);
1 V: H2 m# z" r. b87 }
* u' D" j2 R0 G7 G4 ^8 }% a% F
& q7 g* n+ w" E9 `) B需要说明的是TEA的构造函数:
7 B, h1 V: a2 f4 _6 B1 C& RTEA(const byte *key, int round = 32, bool isNetByte = false);
( [& \! y% j: q: Z3 G1.key - 加密或解密用的128-bit(16byte)密钥。
; v' `! {1 O [; r0 G. T, ~$ z6 G, e2.round - 加密或解密的轮数,常用的有64,32,16。
7 z1 R: ], f a: J6 a3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! 9 o- m6 j4 T3 m; h$ ^8 h6 P1 G. m* Y
+ q0 \ b+ A. \8 m$ C" c最后当然少不了测试代码: |
|