|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" : ?3 U7 G" P/ p( m( T0 X: }4 j
2 #include <cstring> //for memcpy,memset 1 L$ S" k$ O7 p9 j. I* \; W' Q9 j
3 + _9 W4 H# |/ b! U; V: S6 \
4 using namespace std;
4 I+ x& P& \ y6 p0 o8 ^" Q: P 5 ( Z7 ]* R/ Q! F# q
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
9 d# W1 _/ \) k- c1 u2 J 7 :_round(round) : {/ E# @1 ?3 j
8 ,_isNetByte(isNetByte) { , C, A$ g% Q$ c* y8 T& l
9 if (key != 0)
- P3 e" ?: Z! D J* y) r- J/ j10 memcpy(_key, key, 16); ( p4 ^) v- Z8 v l/ C, q' @* T
11 else 0 m4 t* j0 |1 }5 M, S, u9 p' e
12 memset(_key, 0, 16); 5 i. X- v' w' _: ^7 T# t; R4 R1 e% \
13 }
" Z; f4 d+ F, {+ d/ D( G14
, h6 h. Q6 X6 L ?' k+ R15 TEA::TEA(const TEA &rhs) - n2 A! O& ^* I( A8 x' m/ u/ `8 L- W8 }
16 :_round(rhs._round) + a2 `: i2 Q' C: U% B/ s
17 ,_isNetByte(rhs._isNetByte) { , t H0 R) D# ?9 W
18 memcpy(_key, rhs._key, 16);
% @* M2 O+ P$ P. n+ g4 ?1 o19 }
0 C( P7 ^! P8 y/ {20 & D. K% d2 n5 ]! z: x, \3 v
21 TEA& TEA::operator=(const TEA &rhs) {
* P i% M, U0 V; C6 h22 if (&rhs != this) { # q. u2 a& H3 Z" O" B4 L% Y
23 _round = rhs._round; / c7 H, ]! L3 }/ f g m4 q2 W
24 _isNetByte = rhs._isNetByte; ) |' U8 S4 w& U
25 memcpy(_key, rhs._key, 16);
4 a7 `' u; _6 A3 _4 @26 }
, o! `& f( K8 U9 j9 H/ d27 return *this; 3 h/ z2 E- j! g5 Z0 ^# E* c! X
28 }
" D+ W+ u* ~# N4 C4 t29
( x8 ?* z/ l) D0 `30 void TEA::encrypt(const byte *in, byte *out) { 7 c6 G; P: _4 d9 \$ l" h8 \
31 encrypt((const ulong*)in, (ulong*)out); 5 a; M) u1 Y4 r) s5 \* u
32 } 5 x8 C$ G; r, X$ K
33
+ ~! f9 Y. D/ v0 ~( K* K1 t4 u34 void TEA::decrypt(const byte *in, byte *out) {
6 [! C- g) u# i1 J35 decrypt((const ulong*)in, (ulong*)out);
3 W) N& }$ G- C- D; v36 } $ F$ F3 ]8 E; t
37
# }# p. F# F5 Z* z6 _3 l38 void TEA::encrypt(const ulong *in, ulong *out) {
4 Z5 ]% r! N; X# H8 M$ B2 h) D. V39 4 F1 [1 ^1 N+ ] Z
40 ulong *k = (ulong*)_key; $ Y+ c3 Q; s/ I. z
41 register ulong y = ntoh(in[0]);
& Y3 n+ i/ j* f. l& O42 register ulong z = ntoh(in[1]);
. ]1 f' J; g5 X8 ~* I, f43 register ulong a = ntoh(k[0]);
: Y1 |: p' y3 P# C& h/ s44 register ulong b = ntoh(k[1]);
3 G$ M; u. z+ X$ G' S45 register ulong c = ntoh(k[2]); 5 J8 {* e A T v$ N
46 register ulong d = ntoh(k[3]); ( I& I. H6 n9 b* T/ R5 W# }* j
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ $ b" X; P1 B: w o) b
48 register int round = _round; 9 O% ~# J! Q+ O9 L- t
49 register ulong sum = 0; + p9 K! C, u* }& i: j; y$ g7 f
50 * u; N, K1 B- A9 L2 p
51 while (round--) { /* basic cycle start */ ; l: ?8 B! r$ m; L- S1 z
52 sum += delta;
4 F4 p! r; S3 [$ h) b6 U) S* ~53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); 3 M/ L! K; L2 b0 j7 m. g
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); 3 E6 F+ b/ D# b+ I" I1 |
55 } /* end cycle */ 1 I; F* c1 b. | s, K* t
56 out[0] = ntoh(y); 1 E+ r- }! C2 W
57 out[1] = ntoh(z);
& j. N8 B3 o( v$ |, ~2 G2 |7 F# P58 }
, o- c, ~ u W8 I; L3 C59
# D! Q5 A9 P% u# f: E; k5 W: h60 void TEA::decrypt(const ulong *in, ulong *out) {
0 k e7 u; p/ V61
$ F) ^: a9 F/ T$ S- R( P5 d62 ulong *k = (ulong*)_key;
H) @! b' s" E5 ?; ? e- r2 X X& ]63 register ulong y = ntoh(in[0]); % q& d' V5 m8 x) Y/ P( P
64 register ulong z = ntoh(in[1]);
5 a- \5 B/ {' [3 [% @65 register ulong a = ntoh(k[0]);
2 P/ @4 p& T/ ]$ n# A9 v66 register ulong b = ntoh(k[1]);
& f3 [) d9 \/ a M E3 _1 A67 register ulong c = ntoh(k[2]); l( f( u' V6 i" [ K; f
68 register ulong d = ntoh(k[3]); ) m' n2 e2 m+ o4 x
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 3 P* c: E* a# [
70 register int round = _round; / ^, s3 ~5 H% e% m8 p- n) |; i
71 register ulong sum = 0; 0 |6 Y1 K$ Y8 `' v- M# x* e2 V
72
6 ^& }- X) k9 g! d" C% V73 if (round == 32)
& L: O# J t' M- K) }74 sum = 0xC6EF3720; /* delta << 5*/
0 V/ [) M9 D/ o0 k75 else if (round == 16)
/ X# q; C. \; [+ Y$ A/ a, R$ H76 sum = 0xE3779B90; /* delta << 4*/
7 Z" K4 D4 p$ P7 K1 \& `# b77 else / l: C0 l: o4 |3 M" ]# S0 U
78 sum = delta << static_cast<int>(logbase(2, round));
; u6 o2 I7 w7 h! C3 R* h2 e79
+ g: {% h; p* l' [6 Y80 while (round--) { /* basic cycle start */
- \+ y0 m4 t$ I2 n81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
+ ?6 n8 I `& A+ I* z6 M82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); : ~% r2 h+ y# A+ o/ q* C* T
83 sum -= delta;
0 K7 \# b9 n% J' q84 } /* end cycle */
6 ]9 ^( s7 C: o6 h( _8 x85 out[0] = ntoh(y);
7 m% i/ A' ]/ n4 X$ Z7 m4 e/ ?86 out[1] = ntoh(z);
2 Q* _4 U4 q' [# N; H i% Q) @; g87 }
7 H6 J7 h8 |# B, x6 O8 I$ t& k+ W/ X- P1 s1 H. d* G) s6 {( j
需要说明的是TEA的构造函数: 6 n A b- G; k! q7 Z, `
TEA(const byte *key, int round = 32, bool isNetByte = false);
# E; [9 v" g2 I" \$ a% [, x& c1.key - 加密或解密用的128-bit(16byte)密钥。 ( H8 W0 q! X9 U7 L
2.round - 加密或解密的轮数,常用的有64,32,16。
- ^& P' K1 R* j u" m @3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! & R6 V/ M4 v. T7 I2 f
4 }$ V. U q* E" D最后当然少不了测试代码: |
|