|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
8 r) v4 C2 ]$ i! t$ b4 Q' Q 2 #include <cstring> //for memcpy,memset 7 I4 u0 }: q3 `% f0 z. H$ {
3
% S* H9 P' D( t 4 using namespace std; ; H0 T: _3 J6 T, d
5 " m+ o5 O6 Q- U& s. }! S. r
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) ' J$ G5 S; Z8 w, ?7 R2 X8 l
7 :_round(round)
. m( a# B7 N. e2 S2 k 8 ,_isNetByte(isNetByte) {
1 y6 U8 V) s: j/ c L1 b 9 if (key != 0) 9 s5 h r5 {% y/ F* @! D& K( F
10 memcpy(_key, key, 16);
3 i0 y) K. x/ X# t11 else
5 Q5 u: s+ ?8 B3 ?( k# o12 memset(_key, 0, 16); $ u9 ~! W$ ?" U2 i7 f. f
13 } , o! f' S. Y+ ?3 v% o, h
14 ' H4 u, Y. J2 Q8 h5 [3 f* n+ \. J5 k8 i4 u
15 TEA::TEA(const TEA &rhs)
, s4 W! c, X( a2 U v7 @* |16 :_round(rhs._round)
* b, e! t& @- j; z5 I( x- A7 v17 ,_isNetByte(rhs._isNetByte) { 5 z" J8 b* ?: ?$ e
18 memcpy(_key, rhs._key, 16);
! `8 t# S+ \# Y# r" ~19 }
1 i' p# X; d2 p M4 w20
, Q; k T1 _/ v) c( Q21 TEA& TEA::operator=(const TEA &rhs) { ! y& p! I9 [ P
22 if (&rhs != this) {
' r. ?) Y3 V6 S/ Z23 _round = rhs._round;
W/ U' K6 L1 H+ Q24 _isNetByte = rhs._isNetByte; y4 Y7 a+ A) u6 g6 @
25 memcpy(_key, rhs._key, 16); 7 E+ a, x" Q+ ?7 }% l8 J
26 } j0 _ a: ^7 f7 {2 j
27 return *this;
, P! a# c5 Z2 b# R( G7 x5 j28 }
6 t* e; l7 K, C% D% q' p u2 y: K$ S29 , H* ^- f6 M8 s+ O
30 void TEA::encrypt(const byte *in, byte *out) {
- `5 S+ b9 J& N/ V5 w! E. W( M31 encrypt((const ulong*)in, (ulong*)out); 6 t: `# N" M% y3 }7 a3 [, z* T
32 } ; H& \' z/ i$ D) E! b2 \8 }
33 % q( F9 f2 T0 W5 v9 w
34 void TEA::decrypt(const byte *in, byte *out) { " U$ c; E9 F% |
35 decrypt((const ulong*)in, (ulong*)out); 2 X3 q. E/ S! A0 G
36 } ( U# ^; Y+ U; q- N) Z' x9 |
37 6 h! Y/ R! i( n7 q0 N8 a5 z
38 void TEA::encrypt(const ulong *in, ulong *out) { 6 f6 C2 g$ d7 g* z4 E# r+ r) p. Q
39 ; }3 Q9 k( P1 [0 T7 ~# Z+ N
40 ulong *k = (ulong*)_key;
- [4 `% ?( R3 }8 |% ^7 B41 register ulong y = ntoh(in[0]);
& R. X* ~/ }0 E7 b: C. T |42 register ulong z = ntoh(in[1]);
* Q- f' l" d4 s: i43 register ulong a = ntoh(k[0]); 6 F( g4 j/ K5 M
44 register ulong b = ntoh(k[1]); ; V( g5 [ i! g
45 register ulong c = ntoh(k[2]);
. J2 x1 y! P. o( k- q46 register ulong d = ntoh(k[3]); ) G% [3 s+ Q" A, P
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ P% W8 V* L$ a% I0 M; n0 n
48 register int round = _round; 2 ]9 e* \. p) k. g
49 register ulong sum = 0; ; R( b8 \4 ?) `; [
50 ( T' E' M1 v8 J% v9 c' @
51 while (round--) { /* basic cycle start */ % V7 j/ O. N" ^2 W2 Z! g
52 sum += delta; ! q# G9 D3 w& L- s' B) `: l
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
9 ?- T" u" W$ @) i2 j6 L }54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
. h! A( B0 S% b* y7 ] P55 } /* end cycle */
( _: \3 `% I& T& s56 out[0] = ntoh(y); * n0 F# C, k J$ ^
57 out[1] = ntoh(z);
! h* j% }! K) s9 s( j/ D8 ?4 d' s) S' Q58 }
0 W/ f; h# }' F59
8 X$ X# C. |2 b0 G: _; z7 F60 void TEA::decrypt(const ulong *in, ulong *out) {
& T+ _- @: G+ e% M/ l D% h: {8 M61 4 Z9 L) s& H) J0 @. A5 L
62 ulong *k = (ulong*)_key; 9 V% Q" J- i: B6 }+ ?3 v' n! Z6 F
63 register ulong y = ntoh(in[0]); 5 Q$ H- i! i0 e* Q( L/ e; g1 V
64 register ulong z = ntoh(in[1]); 9 P/ x3 }8 E: u9 a7 t* C0 v* C N
65 register ulong a = ntoh(k[0]); 4 r, X- F3 v+ h: `
66 register ulong b = ntoh(k[1]);
B- s$ p. F+ C C! z) S67 register ulong c = ntoh(k[2]);
. s$ @' h2 u7 s5 \5 t7 ?4 D5 k68 register ulong d = ntoh(k[3]);
& O( E Q- m+ A69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ }2 A+ U9 D4 K$ c* D2 c4 e
70 register int round = _round;
+ A5 i N( E4 f71 register ulong sum = 0; 2 s$ U; G9 x6 Q5 z9 S5 a
72
8 W" e6 \, N+ Q73 if (round == 32) # [* e; K; d" I5 _
74 sum = 0xC6EF3720; /* delta << 5*/
, E6 L* C5 v5 [' ]/ d75 else if (round == 16)
, }" e& K$ M$ D' l' P76 sum = 0xE3779B90; /* delta << 4*/ 2 q* Q# t7 |* A; s7 i5 ?
77 else
. A( I( L- i" ?6 J& j6 e; X! `, w/ R78 sum = delta << static_cast<int>(logbase(2, round));
( j" N. L+ Q( [$ ]8 R79 8 m4 @ b: u7 {1 o9 Q
80 while (round--) { /* basic cycle start */ & A F- }% z! v! y1 t
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
8 J9 ~4 L# k; b; ~82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
5 L% h% T3 ]) M H$ f9 _2 d83 sum -= delta; 6 q {& v5 Q! Q9 i0 I7 J, }" M
84 } /* end cycle */ 4 s, H0 N3 T5 L% Q: t S6 C- f; ^9 m
85 out[0] = ntoh(y); 6 ^1 \; K& z0 U1 ?7 w1 L$ C
86 out[1] = ntoh(z); n7 B+ b+ ~/ b. j9 a
87 }6 j9 d& j; f6 O- e
, X6 ?2 K/ z% @- q需要说明的是TEA的构造函数: N8 D9 h8 R( S( Y/ \: V3 ?
TEA(const byte *key, int round = 32, bool isNetByte = false);
, M0 V, T+ w6 T' J* R0 _ z1.key - 加密或解密用的128-bit(16byte)密钥。
# w4 I; D9 \% `) n: n& Y* H2.round - 加密或解密的轮数,常用的有64,32,16。 ! [5 O; G9 B0 [% X
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! , n/ j4 f( C% o, r
% a8 C' f8 p# Y1 R% m+ m最后当然少不了测试代码: |
|