|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" - c" J2 ^3 \3 b m
2 #include <cstring> //for memcpy,memset , j4 h" n7 O: W2 y! L' M# h6 y9 o
3 : B T- S* v+ s4 |4 N
4 using namespace std;
9 k5 N9 y2 g) q6 t 5
. Q& \" N4 h/ E0 l 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) u' g: ^$ v3 Y
7 :_round(round) : n6 F, H: {. T3 e: Q
8 ,_isNetByte(isNetByte) { 7 K/ B& |7 f# c( P
9 if (key != 0) ; q- r4 x% l- g, ?, ~
10 memcpy(_key, key, 16); 2 y- e2 k9 `- M8 @2 M* C& l0 l
11 else
1 [8 r- L* o* M' {; \; g% } q12 memset(_key, 0, 16);
8 r- S0 ?( B! C0 [$ P+ g# D5 `# ]13 } 7 R+ I) X2 a% r& s4 {2 i/ G) q
14
8 T ?3 Y9 a" X3 u3 ^15 TEA::TEA(const TEA &rhs) 6 w. U3 c" S+ ?
16 :_round(rhs._round) ! e, I3 O! U' s- ~- E7 S
17 ,_isNetByte(rhs._isNetByte) {
' \1 ]/ ~4 W1 H$ `, A18 memcpy(_key, rhs._key, 16); $ }6 J4 [2 A) Z
19 } ; \3 ~9 s. V$ A5 Y& I S) y
20
+ h3 G& N4 _8 @' N' X; ?/ j% A21 TEA& TEA::operator=(const TEA &rhs) {
: _2 K0 d; P2 B: |5 d22 if (&rhs != this) { 0 l6 G5 s. L' F" K9 [
23 _round = rhs._round;
# l6 k5 R$ U; I24 _isNetByte = rhs._isNetByte; 8 T; G5 D) F' U; x, E! q" M+ ?
25 memcpy(_key, rhs._key, 16);
4 e0 W9 a' _! i) v- Q3 {26 } 2 L z" C. n& O) b+ N
27 return *this; $ _% z5 [# \# d
28 } % w, L8 _' k$ G* c1 v, D( `1 G8 y
29 , \+ C. a1 w4 d" i7 f7 J" C4 ?
30 void TEA::encrypt(const byte *in, byte *out) { 5 R/ N9 w- b c5 k
31 encrypt((const ulong*)in, (ulong*)out); " ~& [0 u+ b1 r9 ^+ N
32 } & J7 ]: Y- }+ N: M3 C# b
33 3 B0 ^+ ^3 f- n/ T7 ~, K
34 void TEA::decrypt(const byte *in, byte *out) {
+ K/ E+ |: ?9 H7 K35 decrypt((const ulong*)in, (ulong*)out);
" v7 |5 U* ?: J+ R3 Y$ L36 }
6 U" k; E0 K+ h$ f9 m+ B/ R37 * @8 I" V) g) J3 J, N2 L
38 void TEA::encrypt(const ulong *in, ulong *out) { 9 M5 e4 I; G4 Y' V( }, x' f5 M$ w
39 0 s8 ?5 u* ~$ Q7 R- e
40 ulong *k = (ulong*)_key; * \" `% P) w( r
41 register ulong y = ntoh(in[0]);
4 X1 u+ o7 N! j9 t42 register ulong z = ntoh(in[1]); C4 M, G& M/ y
43 register ulong a = ntoh(k[0]);
) V" n7 K/ ^2 ^44 register ulong b = ntoh(k[1]);
$ t5 A" O! B2 C# b45 register ulong c = ntoh(k[2]); , p4 P6 N' Y/ q \4 C p
46 register ulong d = ntoh(k[3]); }. B0 ?% Y( d# `
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ # ]/ v. _' ?$ u8 e. X
48 register int round = _round; 7 m( _: Y5 G: T" e K
49 register ulong sum = 0;
3 o$ R2 N: e6 Y9 I3 v) ]50
W+ o& |4 b7 Q* V51 while (round--) { /* basic cycle start */ ' V! m% R- d( y. P7 u8 A9 x
52 sum += delta;
6 L! g8 S. v6 S; j3 H/ ?53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); 9 g R8 c: e: {# o: g3 U
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
3 F3 v+ \& K# c, j) S55 } /* end cycle */ , j+ r* V" E( v( E
56 out[0] = ntoh(y);
6 \7 t" g, @6 P# \ [57 out[1] = ntoh(z); ' j" m( h0 O0 N! d* P
58 }
5 b. N" [- f" E: K% @59
' J+ C' @4 j2 C2 ?" A, W5 O60 void TEA::decrypt(const ulong *in, ulong *out) {
4 `) Z8 u3 L1 M( }61
" m0 [" @& M% V62 ulong *k = (ulong*)_key;
! w0 i) E1 n1 d$ ~1 Y/ k( V63 register ulong y = ntoh(in[0]); ) u3 Y8 D$ p- |
64 register ulong z = ntoh(in[1]); # t4 v, V2 p- o, q. B! J# f" p9 t
65 register ulong a = ntoh(k[0]); ]) d3 c3 K* {+ @- ^
66 register ulong b = ntoh(k[1]); 1 E! N/ C: y! I+ u
67 register ulong c = ntoh(k[2]); * p9 G6 }" e4 t3 T0 a, Q' ~
68 register ulong d = ntoh(k[3]);
R! [: ?+ }& r; k4 V69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ + O! F2 o# J# v7 d, K' p5 z; k$ F
70 register int round = _round; 1 g- N8 |6 V6 i a5 d) o
71 register ulong sum = 0;
2 y( y& R$ y& @# `) o) z7 ]72
$ h0 _6 Z/ N/ t# B4 X; S73 if (round == 32)
3 j: J3 }( \* ~" a( E- [74 sum = 0xC6EF3720; /* delta << 5*/
4 ~$ S; T/ f1 I. d1 t: ^- e75 else if (round == 16) 7 w( V1 x( g7 O. k/ I( Q- W
76 sum = 0xE3779B90; /* delta << 4*/
% @0 d1 a9 y9 \ W% D) k' g/ W7 @77 else
, f+ t2 J2 r6 P! n# l78 sum = delta << static_cast<int>(logbase(2, round));
6 A& p9 b' {% v2 }4 l79 : k% I& g+ e3 B9 A$ }1 U
80 while (round--) { /* basic cycle start */ : y) `, X, h$ s- k/ l6 ^5 t
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
7 g0 b/ I6 Y+ T0 O* { M1 b6 V82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
, e! O, u& }5 e8 h83 sum -= delta; ) L0 [. g% K- z
84 } /* end cycle */
0 @ d5 c' m% ]1 S3 T" r% u85 out[0] = ntoh(y);
- j% A( J, z2 P4 P6 l3 m; w86 out[1] = ntoh(z);
, N9 _& ~9 L: \1 p& z0 ~! @87 }4 A3 {2 \9 Z% i2 p/ z. _' O
8 B1 _& Y' G3 o9 K" k/ I8 M# V2 F2 G需要说明的是TEA的构造函数: ; }0 u$ V: K k5 t
TEA(const byte *key, int round = 32, bool isNetByte = false); 7 q& w) a& A, t0 A! F
1.key - 加密或解密用的128-bit(16byte)密钥。
/ M+ O9 U( I: Z l/ X. j, i- F( g2.round - 加密或解密的轮数,常用的有64,32,16。 F# n$ l# q5 j: ^6 \& o( v
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
6 M1 S$ J0 g- V( d4 A+ n0 `8 P6 `% e
最后当然少不了测试代码: |
|