|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" 5 c% h! ^" t j
2 #include <cstring> //for memcpy,memset ) g( {) E2 A5 ~
3
% O- v# R4 P8 \6 j8 r 4 using namespace std; " U; Q3 I4 _. Q4 D! `( m4 y
5 5 L. E7 ^7 M8 q' q! [
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) ; h7 x1 U8 T! ~+ \
7 :_round(round)
6 C# D, U" J: c, O' y" @0 ~ 8 ,_isNetByte(isNetByte) { 0 B7 z: T' ~& e; j2 W4 V& w
9 if (key != 0) 5 g. H; k4 Y3 ~& s1 p" k6 ?
10 memcpy(_key, key, 16);
c" Z0 C+ T' t+ C8 W0 E2 @- K11 else & n+ E: R1 V3 r/ g7 `; t
12 memset(_key, 0, 16); 5 k$ m* f2 @+ W. S+ V
13 }
: ?8 @6 ]- e0 U: J) v14
9 m: k4 ]% t2 d5 p15 TEA::TEA(const TEA &rhs) 4 {, L- U" y: o& O! H
16 :_round(rhs._round) % d" ^, [" t3 u0 E n
17 ,_isNetByte(rhs._isNetByte) {
3 E( j( W2 C4 U" R/ o3 H" ]5 c18 memcpy(_key, rhs._key, 16); ) p3 h; i( a) K$ h" f$ [
19 }
; T7 i# R" T8 c- I: N/ s20
1 ^" K# X$ }4 A1 C" p! u( s0 c21 TEA& TEA::operator=(const TEA &rhs) {
/ w+ F; N' s5 g7 x+ H0 }22 if (&rhs != this) { 0 J, T, U" I# J% d5 I4 s$ k! r/ J
23 _round = rhs._round;
- r- U0 C' x" O; J% g24 _isNetByte = rhs._isNetByte;
. C" N, _2 q0 d# Z4 H25 memcpy(_key, rhs._key, 16);
+ v7 z0 {8 ~' ~2 J+ M26 }
" `& L p( n) Y- M2 P+ o5 K4 f27 return *this; 7 w3 f. F8 j3 t1 J0 d1 |
28 }
& U. O! h/ A* L, d/ l) N29 / h) j: D8 ` y
30 void TEA::encrypt(const byte *in, byte *out) { 2 \6 P/ D. n5 E6 Q" @4 h* n# E
31 encrypt((const ulong*)in, (ulong*)out); 0 |% Y1 b3 A6 M) O* [: A) ~
32 } . }' g+ R2 J9 K: ]+ a% _
33 * i0 b% W: ?+ E+ q; Q
34 void TEA::decrypt(const byte *in, byte *out) {
2 f) A3 s# ^) \. l; ]% Z2 K4 y35 decrypt((const ulong*)in, (ulong*)out);
. }/ W. a6 P" Z; L, \36 } & A4 \4 f9 |0 ]3 a7 i( |
37
5 k. F, e; ]1 \+ F, n38 void TEA::encrypt(const ulong *in, ulong *out) { ) x$ Y0 W; r" c" b% Z
39
! l! y3 d' v* f3 D. n- W+ p40 ulong *k = (ulong*)_key;
3 x* b5 c" M+ R0 a6 q/ l7 o) Q41 register ulong y = ntoh(in[0]); 5 {1 O8 E0 J0 b: l% z/ l
42 register ulong z = ntoh(in[1]);
9 E2 @$ b2 e* \% h- s- f( \43 register ulong a = ntoh(k[0]);
) P% u4 p S; v/ Y$ M X1 R8 x2 `44 register ulong b = ntoh(k[1]); : C3 S( T# X0 h; \; J7 l3 Z
45 register ulong c = ntoh(k[2]);
% l' M7 b3 |2 D0 R46 register ulong d = ntoh(k[3]); + c' y9 G9 r" ~0 ?/ O2 F
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ % X; j$ d; ?8 G9 W S
48 register int round = _round;
+ S F- V. w' s' z: y& ]49 register ulong sum = 0;
% K; v' h/ R6 M9 v* s6 u I1 s' J s50 - X- S" I6 C$ O
51 while (round--) { /* basic cycle start */
% i/ B1 p8 d' l# |" B) C K4 o52 sum += delta; 4 C3 y: p! s9 ?7 }' E2 g" ]6 h
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
) G; a+ i& D9 H; F54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
. S5 n3 I5 X; Y$ p+ ~5 W55 } /* end cycle */
+ ~, K5 c/ m3 o7 g9 |' _ A0 ]56 out[0] = ntoh(y); / I" f4 e1 Q- w! s7 g" @
57 out[1] = ntoh(z);
$ L- P& p2 L7 m+ m& _58 }
R, t% S- A$ [. U* H: H9 K59 9 z# }6 S4 z, ^. s. s9 z0 m* R, z
60 void TEA::decrypt(const ulong *in, ulong *out) {
5 e, q- X) B0 S61 3 q+ S, D$ F6 Q1 T
62 ulong *k = (ulong*)_key; - h% T8 F7 C4 g
63 register ulong y = ntoh(in[0]); & q1 Y ~* e( U* D% Q N% G/ }
64 register ulong z = ntoh(in[1]); 4 c" A& x& ]2 l5 Z
65 register ulong a = ntoh(k[0]);
) R. v- Y4 F4 f" Y66 register ulong b = ntoh(k[1]); 8 K9 V9 u7 j: S& p e
67 register ulong c = ntoh(k[2]);
7 G8 N# U7 o, o: R. L- i1 r4 v68 register ulong d = ntoh(k[3]); " @& j& w/ b z; k4 b, s
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ ) G9 A2 q# x: I4 v; @- F
70 register int round = _round;
5 l T Z% r/ i71 register ulong sum = 0; & P. |( l" ?" R+ V7 C! G, d% p+ z
72
- N3 h/ x( y5 m3 u# U73 if (round == 32) ( N# _4 G& @ s. d% _: F
74 sum = 0xC6EF3720; /* delta << 5*/ 9 G1 a5 G" C2 o6 @
75 else if (round == 16) ! k! l; |9 N: u$ k0 F. t
76 sum = 0xE3779B90; /* delta << 4*/
2 p3 B c E8 \/ }77 else
; X2 j8 J0 b' [) Z8 h3 u0 _7 s78 sum = delta << static_cast<int>(logbase(2, round));
$ t! z% n3 T# O0 w- p6 r$ G/ \3 P Z' e79
. M* }# K, u0 H( X( y80 while (round--) { /* basic cycle start */
' i' h+ z1 F Q4 i( u3 [81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
% E8 z! ]8 Q* m/ F9 F7 V5 j/ X82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); ) I! P3 u6 V* I m8 I/ G
83 sum -= delta; 2 Y* B1 H+ N0 |" M& R
84 } /* end cycle */
_' W! A( J) u( ]85 out[0] = ntoh(y); 4 e" r9 O5 R1 p+ Z5 I
86 out[1] = ntoh(z);
/ |" p- B; n& y4 i' q87 }! l) o5 u4 f. U% ] [, R
; W, n6 Z+ r# E0 v. o4 V需要说明的是TEA的构造函数:
$ y* I0 h# Z# g" s8 H, CTEA(const byte *key, int round = 32, bool isNetByte = false);
8 n0 Y- h- H5 t/ y. t P1.key - 加密或解密用的128-bit(16byte)密钥。 - y- N, v C' t% _
2.round - 加密或解密的轮数,常用的有64,32,16。
) x7 E3 M) T( K+ e8 Q$ t! I+ s3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
% l2 e- ` q% c+ T0 J% T3 ^4 u1 g4 V9 j
最后当然少不了测试代码: |
|