|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" 5 K. Q3 v; j; j5 a" K! D' L
2 #include <cstring> //for memcpy,memset & a# @, E# I0 O0 o
3
0 G! z# r, `/ d5 A; m4 z4 d 4 using namespace std; - h# [& ?. t: O0 t5 R; p
5
) D" a3 C- Z* ~: s* v* J1 W, q 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
! ]( w ^/ _3 Y' x1 Z6 ]+ O 7 :_round(round) 9 r Y( v1 d4 G5 O3 ~8 ]
8 ,_isNetByte(isNetByte) { 5 Q4 C7 x/ y! A: S
9 if (key != 0) 6 p- o4 }6 E" d! S4 u
10 memcpy(_key, key, 16);
* j& k, b9 x+ E0 ^2 `& w9 W11 else 0 w' r% I/ g- l' Y* a9 P
12 memset(_key, 0, 16); % S; y# a. q8 R1 W( V& K
13 } # U- k% g; p% z7 Q# W3 r3 Y4 p# M% J
14
4 Z8 S) H1 ?' u15 TEA::TEA(const TEA &rhs) F1 i7 d1 y) |7 V8 ?2 y% G) [1 s
16 :_round(rhs._round)
. A8 h# A6 _" Q17 ,_isNetByte(rhs._isNetByte) { 1 @: }/ f3 M2 L
18 memcpy(_key, rhs._key, 16); ) s+ ?/ U, u. K R. E2 V: W) L
19 } & m; X2 i% ?. F$ a1 K4 }
20 $ t2 R- i" }! l6 z9 p7 P. d
21 TEA& TEA::operator=(const TEA &rhs) { ; A4 [' Q+ ~9 I" U: ~" }
22 if (&rhs != this) {
5 B* R' f( A. G/ B23 _round = rhs._round; 3 s m! P0 _9 N" T( [% e0 E
24 _isNetByte = rhs._isNetByte; # n: w! d, R+ N* G6 H) G2 \+ V
25 memcpy(_key, rhs._key, 16); ! N5 Q! n6 K9 _5 R: x# C U' t
26 }
& o9 x7 }6 F8 x. O6 p- `% Z27 return *this; 9 _2 A) A& o3 i
28 } 6 F6 Q% ~! }- j
29 - x& K: X6 g' s% w
30 void TEA::encrypt(const byte *in, byte *out) {
* _; x9 } ^0 H31 encrypt((const ulong*)in, (ulong*)out); * l/ c5 y; m, G4 y, H
32 } " R: | {1 p9 H2 }( W
33
, ?2 T) k0 T" n34 void TEA::decrypt(const byte *in, byte *out) {
$ |% e7 A. @! L) X! y35 decrypt((const ulong*)in, (ulong*)out); ' Q) s% u2 p" y5 l6 ~' S- P6 l
36 } & u; R/ W4 O8 W# I" z
37 $ ]; a) k: u( J& E( \& B
38 void TEA::encrypt(const ulong *in, ulong *out) {
# E; z! l1 W6 ^$ t; j39
% m* N5 W& q1 Q' D4 q7 U0 j9 ]40 ulong *k = (ulong*)_key; $ _! T" S3 @" o( _ Y
41 register ulong y = ntoh(in[0]); 2 n1 X" ^$ z8 R, N0 P- I" o
42 register ulong z = ntoh(in[1]); : T$ ~4 T: R/ S% U% Z; b$ W" _0 ]
43 register ulong a = ntoh(k[0]);
- ]! I' Z% W) c' K% F* ~# M, W; {44 register ulong b = ntoh(k[1]); ' P0 [& J% X8 ~9 N
45 register ulong c = ntoh(k[2]);
, ~, v' ?2 s1 m& L# h* r46 register ulong d = ntoh(k[3]);
: |' N& E% p3 L K! Q47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
$ A- W+ m5 q; {! j0 ~ R% q; w4 X48 register int round = _round; ; z9 M! n3 g/ I2 r6 _2 ^1 |3 H) S
49 register ulong sum = 0; 7 d; x: g6 G3 q4 C9 X! h- ~3 n
50 / _3 n* C3 ^( M- h
51 while (round--) { /* basic cycle start */
! @3 u2 g7 ?; {52 sum += delta;
6 R+ i- \$ [0 k9 \( T7 c% F53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
2 b: i" M! m& h: o54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); ' J: f, D* }# z
55 } /* end cycle */ / G& e' y2 U* l6 r2 ~3 C+ Q1 D7 e
56 out[0] = ntoh(y);
/ F/ x9 L/ N) H0 E0 z2 m2 I% G$ R57 out[1] = ntoh(z);
/ u$ a9 I/ B5 J6 K2 O3 C58 }
. h4 ?& c& }1 I8 K3 |2 n59
: S' v! @9 I$ m0 H& v% ^60 void TEA::decrypt(const ulong *in, ulong *out) {
9 e) C- F p4 s: C( I61 , H* ^2 |' [6 a: Q) h0 M
62 ulong *k = (ulong*)_key;
( ^/ C" o- ]7 q. ~/ V* }63 register ulong y = ntoh(in[0]); : O7 i+ N/ _8 T4 q7 M' ~
64 register ulong z = ntoh(in[1]);
; _) S% R+ o- E65 register ulong a = ntoh(k[0]);
2 o/ z' |) A6 X66 register ulong b = ntoh(k[1]);
2 l3 v$ H1 W! e/ |0 N1 [ L, u67 register ulong c = ntoh(k[2]); ; r% T% A1 z; ~
68 register ulong d = ntoh(k[3]);
( X# H, J4 K; D! k4 G% S5 }69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
; b: b" R9 n# }! @70 register int round = _round; ; M% }5 w1 _0 M1 G9 a. K1 v
71 register ulong sum = 0;
: ^1 w( X& E* e6 Q0 A72
0 K! S& g8 C' j8 c73 if (round == 32) - L2 u4 @/ ?5 y7 V# }
74 sum = 0xC6EF3720; /* delta << 5*/
" m$ I8 n/ R6 t, {3 E+ `75 else if (round == 16) 8 x# t3 F8 M7 ~6 a! b
76 sum = 0xE3779B90; /* delta << 4*/
0 Q/ ~& I8 r* S77 else
0 r5 R" d$ L+ \78 sum = delta << static_cast<int>(logbase(2, round));
+ L% X5 |/ n7 G' J1 L) t' X8 Y79
0 C7 t0 w/ M' U" q" b80 while (round--) { /* basic cycle start */ - l5 T6 ^! J! {# e4 Z
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); 1 V5 e1 W% C+ y4 s' d: n6 ?! Y! m
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); 5 S4 W0 x# V7 y
83 sum -= delta; ; g1 s- k* B" g. V+ l; A, y
84 } /* end cycle */
) f7 ^" K/ P+ C9 i3 X9 R; a85 out[0] = ntoh(y);
4 C, r `, j) Q) ~$ T86 out[1] = ntoh(z); ( h. p' }: i1 U8 E* `
87 }+ y3 ~! b( k5 ? V( z* q7 x- w
7 M/ G7 x# ]# v* t% {
需要说明的是TEA的构造函数:
6 v* C1 R' }# ?% yTEA(const byte *key, int round = 32, bool isNetByte = false);
# p( P, d1 B3 v: y5 y1.key - 加密或解密用的128-bit(16byte)密钥。
+ S$ n- }' \& s) V2 d. k w2.round - 加密或解密的轮数,常用的有64,32,16。 & I" h" g' C$ f9 ]5 r
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! + q( ~3 b; [0 @6 h: C/ O
) S+ X- j* s9 I( R" M% t最后当然少不了测试代码: |
|