|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" 9 c1 ^( R1 d9 N4 x/ U5 s/ j
2 #include <cstring> //for memcpy,memset + H& R2 [+ g0 L$ ^
3
0 k5 ~9 Y( a* {) y# s 4 using namespace std; 5 u) y3 H8 C, L2 ~* a- Y
5
! o: \9 Z. N: J2 }% A" {) O 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
: u/ {$ V+ p. K6 H4 \0 o5 {# w* z 7 :_round(round) % _" ~, I4 [/ O) e
8 ,_isNetByte(isNetByte) { & w0 D+ U" @' | K5 V! g
9 if (key != 0) 2 t/ S( ^6 k$ l4 [) X
10 memcpy(_key, key, 16); & \( G) ]1 Y- w+ r9 V& v! W
11 else
8 S8 V8 f1 |- S3 k8 O12 memset(_key, 0, 16);
2 k, R% M/ [( D0 n3 e* v13 }
8 [ B6 W9 T5 R5 D0 f$ @2 G* d1 q14
- y& P) R; @" N2 S' G15 TEA::TEA(const TEA &rhs)
I. T7 O4 j7 \: y* i16 :_round(rhs._round)
& n% m/ A! a/ f. ?5 {17 ,_isNetByte(rhs._isNetByte) {
G0 r$ o' u. ] J4 Q7 l* Z5 [18 memcpy(_key, rhs._key, 16); 3 W/ e* j4 A8 A! K& n. y
19 } 1 s2 U8 h: ~& s1 V( B1 v" V
20 0 v1 F# c# x9 A& G0 t& ?% G
21 TEA& TEA::operator=(const TEA &rhs) { + ^( ^. N$ t7 s- S
22 if (&rhs != this) {
; A) a8 A( A! p, Y$ `23 _round = rhs._round;
4 ]3 u( p, s2 n& {1 u24 _isNetByte = rhs._isNetByte;
7 Y9 O5 r/ v% X- @% o. I25 memcpy(_key, rhs._key, 16); Q" z N" K% x2 A0 J, B8 ?
26 }
" D) M1 d# a5 m27 return *this; $ H, v1 E8 ]' u. ]; y+ @
28 }
% G2 w8 h- @/ Z29
% n% E* ?, m" b30 void TEA::encrypt(const byte *in, byte *out) {
3 Q4 T: F! W7 _+ U! i9 T4 c, E1 A) ], b) z31 encrypt((const ulong*)in, (ulong*)out); " u* ?2 o+ |1 X' E) P7 Q+ t
32 } ) p5 {, d, L/ ?( y$ `, ^# S1 G
33 ' d V5 R& x1 I# j! M- |
34 void TEA::decrypt(const byte *in, byte *out) { ) Q3 L, o4 v% h: a1 u% t
35 decrypt((const ulong*)in, (ulong*)out);
7 f/ J* g, w" y. Y36 }
R" t: @: s0 O3 Z37 5 M6 H2 F% p' D9 h2 t7 Z
38 void TEA::encrypt(const ulong *in, ulong *out) { - Z7 L% k( m2 H: I5 y/ O o; y- G8 a
39 1 c7 T: l" b2 l- E/ b
40 ulong *k = (ulong*)_key; z! K0 [- @1 V) [+ y" w3 R) b
41 register ulong y = ntoh(in[0]);
) e: ?- Y8 K7 s" K9 t# n6 l42 register ulong z = ntoh(in[1]); : E4 y' Y; @% P- T: A4 f; ?8 D
43 register ulong a = ntoh(k[0]); ! n7 @/ D' W0 G. c! X; q# }8 M
44 register ulong b = ntoh(k[1]); + g% g% Z* t' h2 r8 @' u0 {+ t3 |
45 register ulong c = ntoh(k[2]);
( T% d; {% l* s. y' Z0 r46 register ulong d = ntoh(k[3]); - J/ y/ d: Z v& f
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
- Y& y; f$ W7 }( }1 c: f9 A. }2 ]48 register int round = _round; 6 P, g. |+ F" c' `/ V- D7 d
49 register ulong sum = 0;
/ |8 N; r# L# r0 a. {: [' o! l4 w50
! J2 p, y2 n# s5 a51 while (round--) { /* basic cycle start */
; D! z# R* U' y52 sum += delta; & S- _ ?1 y8 [4 V) i
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
, X; n: x% `4 W$ [# f+ c2 Z. h54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); * U% |& b* Y. h& h! Y# v. V0 X; z6 a
55 } /* end cycle */ 8 `5 Z. ^9 k3 |0 U7 }( z5 e3 c7 J
56 out[0] = ntoh(y); 3 w) Y0 Q( r9 B' @* x
57 out[1] = ntoh(z); + K, m# b, L8 Z. A- K
58 }
/ M' U2 |: P, o5 q6 }0 s59 : S& U2 B# b2 e: s, o q
60 void TEA::decrypt(const ulong *in, ulong *out) { % z0 l8 }$ c" n+ Q9 s* {- c
61 ) t8 o E" `- H
62 ulong *k = (ulong*)_key;
) z8 z; U1 f3 F3 l0 W( _1 w63 register ulong y = ntoh(in[0]); % ?9 }1 c3 m0 u; R( I. ]
64 register ulong z = ntoh(in[1]);
' j5 \0 `" y7 R; E1 c6 R65 register ulong a = ntoh(k[0]); 7 P4 `" d6 u) F( o2 d) S; D
66 register ulong b = ntoh(k[1]); ; h! A( `6 m# j4 o3 [# k% @
67 register ulong c = ntoh(k[2]);
0 E* [0 V7 o7 j9 b7 r- q# p68 register ulong d = ntoh(k[3]); 1 I0 D/ w3 Z, \) X, U: D
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 6 C: Z: |3 _2 Z) ?1 {* S
70 register int round = _round;
' Y: n+ a6 ]' L: B2 o" j, o71 register ulong sum = 0; . ~! _9 W* f7 V. S$ |, o
72
# C' r4 j1 Q ?73 if (round == 32)
) n' n) [5 G$ V74 sum = 0xC6EF3720; /* delta << 5*/
, _& F3 e: q2 y" {8 O8 s5 h/ ?75 else if (round == 16) 4 ]2 p/ w! `& O- V. m* K: W0 B
76 sum = 0xE3779B90; /* delta << 4*/
# f/ g0 G. m& e5 p8 {9 _77 else
$ p: d$ ] p. U# X6 r78 sum = delta << static_cast<int>(logbase(2, round));
, q6 E$ x. f2 n/ V* {79 . z1 p, U1 ?9 z+ l6 ^3 B
80 while (round--) { /* basic cycle start */
0 I/ G4 y% N8 A+ g3 h9 c( g81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
8 @: N( Y7 _: x( ?82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); 4 J" }: x7 ^" R2 h# D
83 sum -= delta; ( K0 Y+ l- d' v
84 } /* end cycle */
8 E/ e: O2 G' z B7 V4 S85 out[0] = ntoh(y);
4 F% ~9 L: ~: ?1 `. x2 w9 T7 f86 out[1] = ntoh(z); " [( s* c! w" ]! v7 S j
87 }
1 ~- H( j5 U8 [/ U; i* V7 W' I3 V0 ]* i) [ ]( _) v7 J4 r
需要说明的是TEA的构造函数:
8 G; l& t/ z3 l0 ^: STEA(const byte *key, int round = 32, bool isNetByte = false); 1 d8 w9 S8 ]5 n. h7 |
1.key - 加密或解密用的128-bit(16byte)密钥。
) |% q3 S* _; W1 E5 b" ]& y! i7 k2.round - 加密或解密的轮数,常用的有64,32,16。 6 n% x1 q- I2 Q5 a& m
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! 8 R+ ~ ]4 D5 q$ `/ p
9 m9 f2 X+ w* u% k/ E- M& s! h最后当然少不了测试代码: |
|