|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" 6 T, N! z$ J2 j# ~& e
2 #include <cstring> //for memcpy,memset
, k, {: j2 u6 ~ 3
0 J5 z$ [/ ?' i* e+ Z: O 4 using namespace std; 5 Z, p' _8 P9 `: }! h7 [ N) l9 Q8 Z6 t
5 3 I* C# S; z% \7 W$ N& W8 x
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
' p n0 K; `' {% g2 O9 X4 X& ^ 7 :_round(round) 9 {# k' b" A( H8 }9 S, V
8 ,_isNetByte(isNetByte) {
# T# O5 W# ~& O3 K4 {, u 9 if (key != 0) . k" V% _: J3 i
10 memcpy(_key, key, 16);
' n3 _2 }; l1 e& s7 P1 S, W11 else 8 o9 S: |% ?" R
12 memset(_key, 0, 16);
' l! B n3 Z4 s2 a13 } $ X1 M8 S2 M5 b$ Z& X* m
14 ' H+ O$ ]8 ^8 N4 E% Z
15 TEA::TEA(const TEA &rhs) 6 M) p8 \* U0 j- {
16 :_round(rhs._round)
& @+ y$ X% C9 _2 D1 Z! l17 ,_isNetByte(rhs._isNetByte) {
3 c! ?5 ~# h: I& Y18 memcpy(_key, rhs._key, 16); " M. ^: \' c4 c \2 y
19 }
" ]& e2 Q3 I6 n! ?20 , a, C* q, a5 i5 a- Q2 R
21 TEA& TEA::operator=(const TEA &rhs) { % s) X9 l" c8 m7 e( t4 M; r- V
22 if (&rhs != this) {
" D; t9 W* E6 h ?4 N, G' u23 _round = rhs._round;
2 J( r2 z4 W- y8 R# t24 _isNetByte = rhs._isNetByte;
4 a' r6 J4 p6 }25 memcpy(_key, rhs._key, 16);
+ m5 R; E6 O! k$ k) X26 }
$ v" m# f. l- L# A# S/ c27 return *this; ( E! F- c4 @: y" l
28 } 0 c9 {& s3 H8 @, O7 x* }& s
29 + ~7 ]5 ~# k1 ~# n
30 void TEA::encrypt(const byte *in, byte *out) {
8 ?1 p3 C/ l o% O* d5 K. \1 ~0 W31 encrypt((const ulong*)in, (ulong*)out); $ ^, I+ H9 R- a$ N( K" G$ o
32 } ' P! G/ I0 E8 }3 W7 k! F
33
5 v, J3 M" F% [34 void TEA::decrypt(const byte *in, byte *out) {
4 l! y# l+ f9 P8 s35 decrypt((const ulong*)in, (ulong*)out); , l9 R' {2 d5 h: y N U( I# W
36 }
7 n( o0 _/ g. A; g" t1 [8 K2 h37
5 Y" C. I# [9 {4 }, J38 void TEA::encrypt(const ulong *in, ulong *out) {
4 T" [8 S! h0 r- u5 \4 v: c8 J39 4 I2 v' m! v7 \* y
40 ulong *k = (ulong*)_key; ) v1 Y- E7 K9 y6 F
41 register ulong y = ntoh(in[0]); & h- D$ b3 b+ j" @8 e" Z
42 register ulong z = ntoh(in[1]); 5 \4 e `0 |& k( ~: p2 }
43 register ulong a = ntoh(k[0]);
% p& F+ Q/ c, q2 `2 @44 register ulong b = ntoh(k[1]);
0 W$ _9 y, U/ {7 q1 T7 V6 |45 register ulong c = ntoh(k[2]); 8 T7 j2 S1 |$ E5 Q" y+ Y
46 register ulong d = ntoh(k[3]); 1 j. @5 w. D: D( p
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
+ `. W& d% \' T% T3 M! ?5 O48 register int round = _round;
9 U" T, `9 r' { m, Y49 register ulong sum = 0; . L2 C3 F8 t! ^2 z: _. |5 S
50
! W! @' t" @( E- h3 W) X" R51 while (round--) { /* basic cycle start */ 8 u0 s& o @* D
52 sum += delta;
; T `6 O6 K* }* i/ \0 Z) H53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
: O9 E% f7 e4 Q+ x: R54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); 8 F" N& G! ^5 c" t! Z( C# ]# B. b
55 } /* end cycle */ ' `4 F" Q. v8 g& R" E
56 out[0] = ntoh(y); 4 v3 a" Z4 l0 E% A( n
57 out[1] = ntoh(z); ) Z! c4 Y7 i8 @# [7 ~0 X
58 } ; M# C1 V: z7 q
59 : A- f( Y% i4 T/ X( m7 \) [; A
60 void TEA::decrypt(const ulong *in, ulong *out) { / q! ^; k- m4 J# s m/ D( f
61 ) X' i, }. C! F6 Z- d( k
62 ulong *k = (ulong*)_key;
b3 G/ k) V% I7 \# x3 n63 register ulong y = ntoh(in[0]);
* s4 l5 c* o, O! w+ T% N64 register ulong z = ntoh(in[1]);
5 ~3 `# B3 h* e# w3 \65 register ulong a = ntoh(k[0]); 6 u0 ~) U4 t6 H0 v9 ^" ^/ U" ^/ ?
66 register ulong b = ntoh(k[1]);
! S; h2 Z5 f1 h: m67 register ulong c = ntoh(k[2]); # R! l T7 s; g) p+ l- E5 \! ^
68 register ulong d = ntoh(k[3]); * E' d& f4 _( H# V' K; R
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
3 ~2 ~! B2 P5 W8 J+ ]. V70 register int round = _round;
; Q* ~5 K) n; _" s1 n1 R71 register ulong sum = 0; 7 i0 S* X' J/ V6 Y9 r5 E
72
% k. h' v; T2 }; x0 \; d73 if (round == 32)
! o( ~7 N2 ^3 }; {% z- d( I74 sum = 0xC6EF3720; /* delta << 5*/
7 F7 P8 O2 a! ` V& j75 else if (round == 16) # H' p0 d1 R& Z
76 sum = 0xE3779B90; /* delta << 4*/
. h3 c. ` Q1 j, J) o; L' z$ i* ^77 else
. l: l2 g: M( V( [78 sum = delta << static_cast<int>(logbase(2, round)); 4 @! X/ o) M0 y" V- Z |, C
79
! n6 o! A; C( ^" J/ }; a5 u1 c7 p+ ^80 while (round--) { /* basic cycle start */ ( T, @) b0 x2 U
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
' l& ^4 f* j$ R8 @3 X2 s82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); . r! ]6 Z' o* ^: p2 N. `. Z" c
83 sum -= delta; 2 `. n8 ]) T4 Q) n
84 } /* end cycle */ ' c/ | v- I \3 C. `9 M+ @
85 out[0] = ntoh(y);
( c5 @) |; r& m0 c! A3 }- }86 out[1] = ntoh(z);
7 b/ j9 x0 @- `/ p& K87 }" O( e7 u) W% N) T
0 u& Y: `; c& Z% _- X0 @; w; c需要说明的是TEA的构造函数: ( {5 U) U A2 E+ o' b5 s
TEA(const byte *key, int round = 32, bool isNetByte = false); / G6 w2 t: O x4 d- h
1.key - 加密或解密用的128-bit(16byte)密钥。 ! C5 d: Q! a; h( B% {
2.round - 加密或解密的轮数,常用的有64,32,16。
. W K1 s4 ]7 k4 d$ I( o* G3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
1 B) D+ \6 |1 j3 b4 C! ^: |4 h
" }6 ^, W: @! F( Y+ i最后当然少不了测试代码: |
|