|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
. R% Y1 `. i3 U 2 #include <cstring> //for memcpy,memset
4 {) o% z' Q* x5 @0 M9 k/ u 3 ! `4 P6 k' Z5 F. u8 [
4 using namespace std; ' Z) s) U' S: ^( y; B
5 9 l& B7 }4 y. a+ \* A4 U
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
# v: y! y+ g% Q, N) g- w8 ^ 7 :_round(round)
1 u5 R# J! k2 e; u" m2 P 8 ,_isNetByte(isNetByte) {
' b! E3 Q0 M; L+ Z; s# ] 9 if (key != 0) : x- h$ @9 H' N; U/ D6 i2 Q
10 memcpy(_key, key, 16); ( h8 E# |, Q! p- _
11 else
* ]8 i2 b% `0 _( k) E; B12 memset(_key, 0, 16);
3 _2 ?3 T0 K6 M1 m' F13 }
" E# {: J& `3 o6 u! L" ?+ ?% o9 i14 r9 d+ ?3 i6 {; D4 ^+ Z4 s: g& i
15 TEA::TEA(const TEA &rhs)
" \0 D) }! l- T2 V" j# D! M16 :_round(rhs._round) 9 e: Y, F" V9 g2 p/ e
17 ,_isNetByte(rhs._isNetByte) { 4 n9 @5 Q. M# h& I' E
18 memcpy(_key, rhs._key, 16);
+ E$ H8 e% K! \2 I8 T19 }
, ?) O2 G' b2 Q2 x M8 y20 : Y- a3 b' u U0 W& I3 E
21 TEA& TEA::operator=(const TEA &rhs) { 6 P7 v, D+ ? ] x% q6 p
22 if (&rhs != this) { * U2 G) k2 ~- f7 K
23 _round = rhs._round; - W: o- a% j( t. X, E" ^7 p4 ~ b
24 _isNetByte = rhs._isNetByte;
+ @+ v, [2 `1 L" ] s+ H25 memcpy(_key, rhs._key, 16); ( s* t8 G; u. L( J/ y
26 }
9 e6 o* Y K4 j27 return *this; 0 \( i) W$ [/ ~2 w" s7 v* {
28 } # t2 y0 K. l* z. Y0 A% X
29
8 a+ b& | w# {; H30 void TEA::encrypt(const byte *in, byte *out) { : z. w; { ?2 S, A% s. b6 i
31 encrypt((const ulong*)in, (ulong*)out); , m- w& m! R+ }0 z8 A# M2 f
32 }
/ E. I, r1 `5 T& {33
2 i5 o) O& p" [3 {( E5 ^/ o34 void TEA::decrypt(const byte *in, byte *out) { , _7 W3 t( m+ B% c9 U% C
35 decrypt((const ulong*)in, (ulong*)out); ) ]1 c& u6 ^- f3 C; l" h9 J0 Z" w
36 }
6 [ E& c. v! J( G5 Q37
: f. m8 J+ H8 j: I( [+ b$ E38 void TEA::encrypt(const ulong *in, ulong *out) {
: B P* i9 \8 C3 ~% M2 t& @39
% \/ E2 S% `( a0 G& X! V# Q. U1 v40 ulong *k = (ulong*)_key;
) l7 O9 g; M% N( ^41 register ulong y = ntoh(in[0]);
V1 {+ s- g9 c( F( T42 register ulong z = ntoh(in[1]);
# m, D) F; u, e( ]$ q) |/ u+ }43 register ulong a = ntoh(k[0]); 9 N5 A E) f1 z9 W
44 register ulong b = ntoh(k[1]); 9 j8 L& M. R6 y1 r) `6 t
45 register ulong c = ntoh(k[2]);
! `& G2 \9 H) U6 e' \' ?46 register ulong d = ntoh(k[3]); " M# E: ^3 i, z1 V% E) n- u
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
" K' Y% B8 D5 O2 M C48 register int round = _round;
( V- D4 L( Z: g+ Q t2 Q49 register ulong sum = 0; ( b2 D" x5 r' ~7 z; R9 P& C8 k
50
- V/ S, G& z/ t3 D51 while (round--) { /* basic cycle start */ ' _8 _( l$ f: s3 X
52 sum += delta;
" @# v# ?' F3 {: N53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); 5 k @5 i; Y4 y0 b/ E0 [$ h
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
; `4 U2 }% k1 U6 b! s9 x8 O55 } /* end cycle */ - w4 t% K2 E2 w( U+ p8 w' A
56 out[0] = ntoh(y); 2 i/ o' S* `$ e
57 out[1] = ntoh(z); . n4 |0 ?. u6 W
58 } * s5 i! ~6 G. ?' I& f& \
59
) R3 [$ A/ T+ N; n60 void TEA::decrypt(const ulong *in, ulong *out) { 6 x4 D; L) k5 E: f
61
5 S2 `6 @+ h9 K1 L62 ulong *k = (ulong*)_key;
\% ~; {; K) q8 \: r6 S63 register ulong y = ntoh(in[0]);
' `% y5 W6 K2 R! |+ T3 F5 m64 register ulong z = ntoh(in[1]); . V b1 V" ^1 E: a8 M1 q1 ]" D
65 register ulong a = ntoh(k[0]);
, M7 a: U5 ?1 f$ o) P- y66 register ulong b = ntoh(k[1]); 1 j/ _# k. d& y: v; ?
67 register ulong c = ntoh(k[2]); O4 G, K1 S$ ?% z( T
68 register ulong d = ntoh(k[3]); . A3 }+ y' d- B6 F
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
~, @/ ~& S5 R% g70 register int round = _round;
0 K5 F5 @1 y3 v71 register ulong sum = 0; % T" b3 F, z6 o- ?8 Z4 H
72 - _+ w" p0 Z l% I
73 if (round == 32)
1 F) d+ _! O1 h6 i0 ? v74 sum = 0xC6EF3720; /* delta << 5*/ ! ?$ e5 L- m& T B
75 else if (round == 16)
" e3 ~& l7 j, N! k) v76 sum = 0xE3779B90; /* delta << 4*/ * ]/ Z8 }3 F2 W# o5 V3 s
77 else ) d6 S% }. i9 v: L
78 sum = delta << static_cast<int>(logbase(2, round)); , T' F) Y! l3 k7 y5 v( l
79
( ]4 g$ S6 X5 e8 r% ~8 \80 while (round--) { /* basic cycle start */
* e+ w9 D4 G% J8 T, S O, f81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); + R5 }/ Y S* y) @. \
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); - B- C4 K2 l& _& }" [8 |& H) l4 q
83 sum -= delta;
" v W6 X0 E) R* D6 y84 } /* end cycle */
% Y9 d! C% K$ ?, K) v85 out[0] = ntoh(y); ; d+ Q9 u' S: C: _
86 out[1] = ntoh(z); 8 C: O+ C7 l+ w# A( o Q
87 }
, p& r+ W( Q$ [2 [6 B: _; ~& S1 U. Q! f% J+ D
需要说明的是TEA的构造函数: + ^+ J. z' t' p5 |) N A. D
TEA(const byte *key, int round = 32, bool isNetByte = false);
7 r; c; Z( j6 p3 Y5 ~1.key - 加密或解密用的128-bit(16byte)密钥。
+ n3 W. r$ d: m0 i/ F" n# I2.round - 加密或解密的轮数,常用的有64,32,16。
s, _& Q' r; l& s# U5 Q* @3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
+ R* h( a( a8 {4 `6 ~5 z5 l
# w% Q* C: `7 |1 S$ \6 Q9 ~最后当然少不了测试代码: |
|