|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
+ e+ p5 f3 f V! J1 B- q 2 #include <cstring> //for memcpy,memset
& d& l6 _4 A! v4 h6 l* | 3 + L+ K+ L# G# g* F$ t
4 using namespace std;
' l( d) _- C9 J. ` 5 7 a# y5 z7 I& ?- |
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) ( Z) Q# h% q- ~; y) V8 K& [
7 :_round(round) 9 m: \1 P) g; X/ Z
8 ,_isNetByte(isNetByte) { 4 K0 S% M7 I0 k9 }( I
9 if (key != 0) 3 Q0 s0 D" U2 `$ j
10 memcpy(_key, key, 16);
9 |$ ^' C* \) A; }% M4 o" S11 else , |+ p6 N6 p$ N& C) |
12 memset(_key, 0, 16);
, _) y& H* _+ `* g, O0 g) \13 } * c C+ N8 X& o0 z6 o! C' \, Z+ V
14 , X6 f W2 ~: j. J4 L9 o
15 TEA::TEA(const TEA &rhs) & M; Z7 m$ V! s0 a- R: A) p
16 :_round(rhs._round)
z+ _1 V0 z& w: P17 ,_isNetByte(rhs._isNetByte) {
8 O9 X1 h( Y, \2 E9 y+ f18 memcpy(_key, rhs._key, 16);
7 l0 w' X: q; f7 g4 S" d19 } / i. n, R: i) _ `7 v
20 # m5 t! R+ z" A8 E% R( V
21 TEA& TEA::operator=(const TEA &rhs) {
( G/ Q+ v' G& \22 if (&rhs != this) { 0 G- \& ~+ b2 @6 V. K
23 _round = rhs._round; 9 ]5 k- c% p9 b4 c( S" u' U* h T
24 _isNetByte = rhs._isNetByte; & h# s( m/ ~, o. E3 K
25 memcpy(_key, rhs._key, 16); % j( _5 ]7 j, d0 h. N8 g8 i3 T
26 } / U7 b D4 R1 U+ P r% H
27 return *this; ( ^! r6 x$ f1 t' m7 r# m' u% \! Y8 z
28 }
* o& o6 Y' K" o' D5 S r( c z# c29
9 _- _, g3 H, v" H2 X3 D8 z30 void TEA::encrypt(const byte *in, byte *out) {
3 `3 ~8 q$ S# `5 k$ X31 encrypt((const ulong*)in, (ulong*)out);
( f. H& X- E9 W3 t& h% i32 } ' d- m; B. B, J# q
33
/ g W& a6 |( |. j( y) _ v1 w" f34 void TEA::decrypt(const byte *in, byte *out) {
- p) C! {5 f. H# B35 decrypt((const ulong*)in, (ulong*)out);
) r1 B% \! X. b! D" o3 I6 ^1 Z0 @36 } - ?+ x2 k) K! f
37
+ z5 q0 E& x9 S+ Y% p6 M38 void TEA::encrypt(const ulong *in, ulong *out) {
% ^( b- _3 v7 d- U39
6 a1 V) X# I2 P" a8 ~4 `40 ulong *k = (ulong*)_key;
7 e/ Z: p% e+ q+ W/ _! ^3 i' h41 register ulong y = ntoh(in[0]); 4 w0 S2 e7 z/ l# ~' u
42 register ulong z = ntoh(in[1]); 1 n% J1 F8 h. Z, V. G/ ^, _
43 register ulong a = ntoh(k[0]);
3 p4 H) Y8 ?1 ?3 H3 J44 register ulong b = ntoh(k[1]);
4 s/ @5 ?/ P% X4 n" A- p45 register ulong c = ntoh(k[2]); 0 L* U* `! k4 E* `# W
46 register ulong d = ntoh(k[3]);
. C, K- g2 D2 N" H- Q" D0 P47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ g7 h' D" Q$ u( I
48 register int round = _round; 7 Y& j+ G) ~1 F. _" O( m* g% t9 J
49 register ulong sum = 0;
2 [2 G& Z# Y# \0 A' ~50
0 X7 R* d+ G9 o; K7 [8 n" c, w51 while (round--) { /* basic cycle start */
- Q5 x! s6 n" E7 L! X5 ?9 y% a52 sum += delta; % Y. n' O% R. E
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
7 m7 _2 l3 I# B; ~6 e54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
, Y0 ?: z* C2 G. A8 C2 G) R55 } /* end cycle */ + s4 x3 o1 q6 `+ S; T* W. ^: L
56 out[0] = ntoh(y);
: B$ c) S# c9 s/ L: O! ?57 out[1] = ntoh(z);
5 k F8 M) l6 G* Q+ @58 }
* }/ h* d3 V7 l8 a% U3 @2 G59
' ]( B5 E8 \' g& u60 void TEA::decrypt(const ulong *in, ulong *out) {
0 z% }* r( h8 P: g0 q61 & [ [; ?: k) l2 H9 l6 i/ n/ F
62 ulong *k = (ulong*)_key; 9 E4 a* n" |% v
63 register ulong y = ntoh(in[0]); 8 {7 n. d, F/ T% v( F$ [$ H
64 register ulong z = ntoh(in[1]); 8 E0 A) [% z4 E7 S$ g2 J
65 register ulong a = ntoh(k[0]);
8 y0 S( C2 l6 P/ g& c2 E+ K: e3 E66 register ulong b = ntoh(k[1]);
4 a- _- E; j$ g67 register ulong c = ntoh(k[2]); 0 w6 ^4 ~9 l. b2 |0 E
68 register ulong d = ntoh(k[3]);
4 ~; w0 _8 e; D69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ M7 D( H7 U( |' S: ~7 m6 H
70 register int round = _round; ! Z/ W3 b* r$ _* I
71 register ulong sum = 0;
: w% b" V$ c# ?8 N# B72 ; O2 e& O: L8 P
73 if (round == 32) 7 {6 N8 @& Q4 o. l1 N
74 sum = 0xC6EF3720; /* delta << 5*/
; y+ k( L/ t) r3 R- V75 else if (round == 16) & A8 |$ b9 f+ j0 g8 `
76 sum = 0xE3779B90; /* delta << 4*/ _1 ?+ g6 ]* J5 G- C
77 else
0 K. p+ G; L- R78 sum = delta << static_cast<int>(logbase(2, round)); & c: B1 ]/ D, s
79
" e* @; x$ r1 t9 E6 U' m80 while (round--) { /* basic cycle start */ # X1 J+ j; u+ {; m
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
1 C8 ]/ E, G7 a82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); 5 t- p+ g+ n5 n% u# [$ R
83 sum -= delta;
# `' d. n( k5 j7 n0 Q84 } /* end cycle */
0 l) D; ~2 W0 R5 E! g P2 R85 out[0] = ntoh(y);
+ b+ @) t/ Q$ Y4 o$ `* I% R86 out[1] = ntoh(z);
$ ~6 n: v3 \, P: ]; v) ?: B87 }
5 d: P5 `9 V8 D, U- G! G; x9 I5 ~
3 v+ b# G4 e, M" ]% D; W `; I. u需要说明的是TEA的构造函数:
0 I; O/ l# l2 N/ zTEA(const byte *key, int round = 32, bool isNetByte = false);
- _2 Q) n8 L/ ]+ F) `& @/ `1.key - 加密或解密用的128-bit(16byte)密钥。 * D/ [5 {" x& ~( K" J4 c
2.round - 加密或解密的轮数,常用的有64,32,16。 , W, l# G% z4 f( W+ t% }! q4 |5 f
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
% w1 v9 ]9 _0 I+ l9 |8 Z* f
7 _) x+ u. y1 H8 e) B最后当然少不了测试代码: |
|