|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
8 j' c. b8 s. i: Z! ? j5 H' b 2 #include <cstring> //for memcpy,memset 2 s( G5 I2 ~7 r) f" E
3 3 f2 }- ?+ l* S% C: Q' M0 ]
4 using namespace std; - i0 x& {- ?* S7 X: a
5 {2 N4 v" g4 B
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
: I3 x, |# t- V; L! D' E 7 :_round(round)
1 C" M7 H3 t8 c# o( ^! d 8 ,_isNetByte(isNetByte) { ' t2 x% |1 g, v) ]. x
9 if (key != 0)
+ u8 a5 G+ I! C9 A10 memcpy(_key, key, 16);
5 }7 W% y3 [+ G5 U11 else
1 F& [' ]& d5 d0 a" ~7 n3 j% y12 memset(_key, 0, 16);
, E8 _+ K' u2 E$ G7 M w13 }
# a& i) a) F4 A0 X8 K14 2 \( q1 k, g' U: b! a
15 TEA::TEA(const TEA &rhs)
' l; k% V5 n2 d* s16 :_round(rhs._round)
. ]7 w- W7 N. j8 c( Q* P" _ d17 ,_isNetByte(rhs._isNetByte) {
+ \& ?( W) E3 `+ A0 l+ \/ M18 memcpy(_key, rhs._key, 16);
0 l4 k7 c% m5 }6 f6 [3 E2 Z19 } 9 z0 X( Y2 D4 D. `5 c0 u
20
/ k1 ]0 T2 h* W( d6 G21 TEA& TEA::operator=(const TEA &rhs) { # i' u6 b: p: O! j" F" m
22 if (&rhs != this) { & w8 G3 U3 i; o7 I1 y5 C
23 _round = rhs._round; ) }% y) X A; r
24 _isNetByte = rhs._isNetByte;
: d( O' p7 A' U3 @5 U _25 memcpy(_key, rhs._key, 16);
/ O: r) _& l' L$ d. F+ i: T( w26 } ) d( w3 _9 ?$ E% n/ i
27 return *this;
2 @5 n/ U5 z1 @& M28 }
6 T) T. C" |+ ]$ K29
/ ~& h, g% U0 g7 Y2 U" Y, ?30 void TEA::encrypt(const byte *in, byte *out) { + ~5 T- Y: l9 K1 ^
31 encrypt((const ulong*)in, (ulong*)out);
2 f: c1 V# h; b: b32 }
- x$ B) ^) p% y/ K5 p33 4 B1 _6 ]* A7 X7 K) _
34 void TEA::decrypt(const byte *in, byte *out) { ' e8 c9 m x2 u" m3 I9 t/ K* u7 V
35 decrypt((const ulong*)in, (ulong*)out); ( g' T* `: b) B# n% [/ Z
36 } # X: Q( W6 U3 {9 g q) g5 x- g4 n
37
! w6 K8 r/ q, O9 ?* s# s38 void TEA::encrypt(const ulong *in, ulong *out) { + Q( z" k! P9 W
39
' y: f3 d+ P" @- h, J40 ulong *k = (ulong*)_key; % Q+ X8 t: g% Y6 q* i/ U
41 register ulong y = ntoh(in[0]); 9 }1 J2 ~; a6 }5 r
42 register ulong z = ntoh(in[1]);
: s6 ~5 L5 D. I9 A k4 z43 register ulong a = ntoh(k[0]); 8 A1 Q! [/ d7 Q6 |! `
44 register ulong b = ntoh(k[1]);
( N' g5 M1 z) D/ z$ _& G45 register ulong c = ntoh(k[2]); : y; N* H9 A; f5 M0 m9 t8 d
46 register ulong d = ntoh(k[3]); , {& ^" I0 g; Y7 s: V
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 7 m) L8 }( r% e. W" E
48 register int round = _round;
" k5 h1 X; L, W! s$ N49 register ulong sum = 0;
( R0 J) j# j! B3 f50 * n" n+ V4 I/ ? z Z" `5 G
51 while (round--) { /* basic cycle start */ + z: U, W8 A6 W# e; B) m
52 sum += delta; 7 N& A; j6 P( l, g: |. j* v* x; g
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); Z) F; T$ X9 i# a8 K
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); 5 y2 M* ^% k! [' G; i3 i+ d
55 } /* end cycle */ 7 h3 m. b& C8 \3 l& f$ Q6 C4 P8 I
56 out[0] = ntoh(y); / w7 u$ O% L# Q* P) ?. y
57 out[1] = ntoh(z); 5 u& J6 q% @2 y4 e8 t
58 } ) C0 G( T" ~; d, g- d
59 1 q3 I. ?4 e+ ]9 V5 D& s& l% v% l
60 void TEA::decrypt(const ulong *in, ulong *out) {
) k+ S8 D( T8 Q2 _+ K* D61
3 _6 w$ ]- A+ F: x7 e0 {$ X* y62 ulong *k = (ulong*)_key;
; Q) Q+ B, w4 m63 register ulong y = ntoh(in[0]);
: f+ y( j. m4 e6 ^8 C' [64 register ulong z = ntoh(in[1]); $ }5 Q. ]- }* v' {
65 register ulong a = ntoh(k[0]);
) l/ |9 w$ H5 `/ ~' K% P66 register ulong b = ntoh(k[1]); 6 N* j9 T; b9 w0 a6 O3 o4 J' @
67 register ulong c = ntoh(k[2]); : v& e) W2 @6 p& j% @* ?
68 register ulong d = ntoh(k[3]); 6 S9 l, o }# ]" |3 f" \
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
' A- e- h) r* w% e4 y5 ^: T70 register int round = _round;
/ N4 N" p2 T1 }1 T71 register ulong sum = 0;
4 b0 ?$ J; ~' U3 Q& ~2 P5 {72 ' `: L, q; v- J* [6 f# d
73 if (round == 32)
0 ]5 f m) X3 G% k1 D74 sum = 0xC6EF3720; /* delta << 5*/ / K, E7 c! S* |
75 else if (round == 16)
9 G9 D0 C/ F* P8 {76 sum = 0xE3779B90; /* delta << 4*/ 8 W0 e7 i* b1 H7 w; d, F
77 else 3 j3 X3 i: V! o5 v* B
78 sum = delta << static_cast<int>(logbase(2, round));
6 o2 R! Q% i8 X' P" s79
. \. _0 B$ Q, M, T3 d80 while (round--) { /* basic cycle start */ 5 X8 A1 L! ?3 l! r
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
$ s& s* a+ R G: R! A82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
, G9 u: j5 Z2 f9 [, a83 sum -= delta; W+ x4 j! y+ E6 v4 H% ?
84 } /* end cycle */
R$ V" j) G- q) M85 out[0] = ntoh(y); - z- x, W; ]: j9 P# c- Y
86 out[1] = ntoh(z);
# ^& z9 \- W! ^3 R$ b/ G! @* T& n87 }4 ^; j0 c9 [) \+ j( `
" g- [3 v6 u. r4 \* Y需要说明的是TEA的构造函数:
. i% @( Y9 V# w ?1 d, ATEA(const byte *key, int round = 32, bool isNetByte = false);
4 ?3 }% W$ S' {- I1.key - 加密或解密用的128-bit(16byte)密钥。
( D& V8 q$ P \: {" ~( Z* n0 X9 `2.round - 加密或解密的轮数,常用的有64,32,16。
- H3 f, C9 b8 ]3 T# W3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
9 d9 G& N9 n% v5 \, m8 J9 n+ C
2 g/ K; V( N" }" J最后当然少不了测试代码: |
|