|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" 2 D; W7 z/ W( w5 l
2 #include <cstring> //for memcpy,memset
4 f7 d. E( f* H+ w6 N5 l 3 1 W$ `6 |9 `& w
4 using namespace std; . I; T0 d* N1 b
5 ! w+ B! a8 [) [4 H. H, _0 G0 Y# q
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
" q4 x/ Y. X4 Z1 Y* p 7 :_round(round)
0 s2 {4 b1 f* C6 ?1 T% y 8 ,_isNetByte(isNetByte) {
% T0 r+ a0 T3 F& t# A7 ?1 L. Z. p 9 if (key != 0)
* t: S6 W3 Z, n( | m10 memcpy(_key, key, 16);
& s# E" l6 p' A0 @2 V! ` O; n$ w; }11 else / d( j0 G( a' P$ _
12 memset(_key, 0, 16);
% x7 n6 c$ E, ^/ A/ ^8 f13 } ( \& i$ A) M) H( v4 K
14
! h; D3 [8 h4 W D8 a2 H% W8 p9 a15 TEA::TEA(const TEA &rhs) " ^' R/ \6 z! Q% B1 [ n( g4 T/ H4 d4 \
16 :_round(rhs._round) $ Z/ j- O2 X3 i0 | F5 S5 n
17 ,_isNetByte(rhs._isNetByte) {
' ]. M0 v/ ~" S9 N" Y18 memcpy(_key, rhs._key, 16); : _3 Z/ _0 q' U1 j% v" n ?
19 } / p2 H5 l$ n" ?- R. c7 y8 s, x
20 , ^) i/ W# G4 J9 c/ @5 \
21 TEA& TEA::operator=(const TEA &rhs) { & M. k S# ~) s/ G$ \& ?
22 if (&rhs != this) { ' r* ]' t6 N* c$ X. h
23 _round = rhs._round;
v- I1 ]" i a$ d6 N* h24 _isNetByte = rhs._isNetByte;
; e9 E; h( \2 z5 L1 a6 `% l3 p8 K25 memcpy(_key, rhs._key, 16); , r: [: t8 \: B6 o! w# o' `3 g
26 } $ {4 y4 y/ d$ {3 y% F8 L
27 return *this; ! Y6 b4 G- Q" D5 I- m1 Z8 I
28 }
0 u, i: s% h+ i1 D5 y; Y2 w1 s0 i29
* c. ?4 m! T3 {% V2 c- Z30 void TEA::encrypt(const byte *in, byte *out) { 0 \. P7 O: z8 @/ g2 Y" C, f
31 encrypt((const ulong*)in, (ulong*)out); 1 d* L8 p; q7 P8 y6 k
32 } $ O; w- J3 r6 Q9 r/ n$ T
33
. M/ @' Y0 o. p1 @0 v34 void TEA::decrypt(const byte *in, byte *out) {
( L9 M" X+ u. g6 l7 r+ z35 decrypt((const ulong*)in, (ulong*)out);
1 A6 R+ w' Q; O6 M2 I* p36 }
( E3 G& k0 \6 A& s37
$ B! B! U4 s* }38 void TEA::encrypt(const ulong *in, ulong *out) {
! J ~6 d0 l: B" ^39 4 f, f! ~1 w3 W6 r# V
40 ulong *k = (ulong*)_key; 8 g: t5 U3 |. F
41 register ulong y = ntoh(in[0]); * I8 G3 p F& V) f6 m* b9 [
42 register ulong z = ntoh(in[1]); - B$ B: f5 o5 r6 @8 q9 }
43 register ulong a = ntoh(k[0]); / g `8 Z- C: G5 z# G* r$ H
44 register ulong b = ntoh(k[1]);
1 g$ ~$ `# _& ?3 y- O45 register ulong c = ntoh(k[2]);
3 ]/ k# r6 v/ D0 R46 register ulong d = ntoh(k[3]);
" J- f+ q' F0 X l, H6 O47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ + f# u4 f1 Q/ {" r3 u, X, L
48 register int round = _round;
5 V6 D+ c" l) X49 register ulong sum = 0;
' h& L9 O* ?+ |7 f% R50
% A8 L8 d5 A8 Y I/ o( u51 while (round--) { /* basic cycle start */ ( T7 ]( f4 @% s2 f
52 sum += delta;
% s' a/ j5 e; }" \) I' {53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); . \' c% F) d2 p/ k& _
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); ) K4 R$ s2 P- M' c
55 } /* end cycle */
& e0 g( J8 i# n& H, L) T56 out[0] = ntoh(y); 7 [' s1 v+ f- O/ `
57 out[1] = ntoh(z); . ~& n! }& ]" l d
58 } 5 Y7 x: h8 n* K$ m9 P
59 # ^. G/ Z2 A9 k
60 void TEA::decrypt(const ulong *in, ulong *out) {
# L) K* M& c5 q, ^) D. H; C61
; f, |8 v9 ^% q# }3 r) N4 H+ K62 ulong *k = (ulong*)_key; " ~3 e4 `1 d- Y9 Y4 z: P
63 register ulong y = ntoh(in[0]);
- `& e( c1 j$ ?3 [: k/ [ n7 q64 register ulong z = ntoh(in[1]);
1 b& R- W8 K h" D: c% H0 A65 register ulong a = ntoh(k[0]); / Z, q1 t+ N/ D- B9 }
66 register ulong b = ntoh(k[1]);
& F3 S6 R) C8 c! j. [67 register ulong c = ntoh(k[2]); + j) J" t& y4 N$ A' j- X
68 register ulong d = ntoh(k[3]);
( c/ y2 O9 W5 A7 f69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ & V4 W o' r6 f
70 register int round = _round;
. i4 F0 R4 z2 b$ ]% X) \! @71 register ulong sum = 0;
0 Z4 S, C6 }1 d7 U. p+ J8 ~72 5 T( b5 w5 T3 J2 {
73 if (round == 32)
9 z2 m7 o$ l: i9 e6 A74 sum = 0xC6EF3720; /* delta << 5*/
+ ^5 Y! w# k: R( ^4 m( W9 L% P/ {75 else if (round == 16) 5 p4 C, h3 Q& o0 m, r, R
76 sum = 0xE3779B90; /* delta << 4*/ : _5 w' K: L4 z1 ?% ~
77 else
- ^3 u- v( |# H0 i( r4 O, S" H* B78 sum = delta << static_cast<int>(logbase(2, round)); % {- D( A% B) y- A( C: `# U
79
7 L" ^$ m! M0 T* g @- \5 q6 J80 while (round--) { /* basic cycle start */ * X( G7 P- [& H3 B- o
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); j' Y! e. U" E( T* j. K6 V
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); # ~5 o, q1 o1 e5 H. j
83 sum -= delta; Q* R6 Z4 d4 g, m) t; X' k6 }
84 } /* end cycle */
7 r& i: A1 C a1 Z* F85 out[0] = ntoh(y); ( S! @4 `% ]2 L Q {
86 out[1] = ntoh(z);
3 ?% n% M- E3 t, O C. p87 }: d5 p/ q$ Q2 ^$ p; t9 z
* L& d. Y8 o: D" a* E- P3 I需要说明的是TEA的构造函数: # ~$ _% f/ y! K
TEA(const byte *key, int round = 32, bool isNetByte = false); 0 Q! i4 `( O1 |& z- G
1.key - 加密或解密用的128-bit(16byte)密钥。
1 Y3 W; M7 y+ i+ W, \5 L" l" z! P1 ^+ J2.round - 加密或解密的轮数,常用的有64,32,16。
6 l9 I# n: `9 z3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
5 o$ M) `+ _) ?
+ M) q+ @* j( R) A: i! |2 l最后当然少不了测试代码: |
|