|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
: M6 E' _4 g, T% W* R5 N 2 #include <cstring> //for memcpy,memset
1 r- q& ]0 Y- o# d/ O 3
# _; F; j2 o) M0 X) [ 4 using namespace std;
% F0 M6 M1 Z, {! {) }; t- L 5 7 B0 a2 ?; j8 [, D; Z# T
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) / G8 e5 ^: v' P9 T- E9 A+ w
7 :_round(round) , V7 j7 Q& W7 H. b8 J% T
8 ,_isNetByte(isNetByte) { ) B$ F. }- w' v4 Z
9 if (key != 0) # D7 B9 D C! ?4 ~; ]
10 memcpy(_key, key, 16); * |6 k) [% f( p9 ^
11 else
8 `! D6 r3 ~# X& z) x( V, G12 memset(_key, 0, 16);
4 N$ i) {2 C5 ?5 g! ~: |; d- P13 }
4 X5 s) l8 h1 a# c14
% A+ q0 \, t7 G/ G15 TEA::TEA(const TEA &rhs)
5 I& M; E& E7 a7 R/ g: a16 :_round(rhs._round)
; m" k) `8 Q" Q: m/ A* [$ y, k$ _9 e17 ,_isNetByte(rhs._isNetByte) {
' j- Z# e( I9 y) ^7 N. ?" N7 a1 W18 memcpy(_key, rhs._key, 16);
/ x! s: W/ A% G5 ]19 } t' A& G% _8 n9 z% \& `
20 1 c8 r0 J! c* S7 e" C) g. U
21 TEA& TEA::operator=(const TEA &rhs) { 2 L7 F1 N4 @* P/ P2 w
22 if (&rhs != this) {
) P+ a, S. W G- H23 _round = rhs._round;
9 \' _6 z$ O& e* E! @. ^8 Q. \24 _isNetByte = rhs._isNetByte;
n9 r+ y ^* D \; r# d9 u& u25 memcpy(_key, rhs._key, 16); 7 f$ r! T( T& c. @, y
26 }
$ s; y( b; j1 |& l1 ]27 return *this;
/ I& I. t/ ?3 z: ]1 }% E' L28 }
) N" ]( { d6 ~% I' e29
3 \" W: w. }" p30 void TEA::encrypt(const byte *in, byte *out) { / R8 D2 U$ Q' ]4 c8 o
31 encrypt((const ulong*)in, (ulong*)out); ) c' |) v* U9 G* i
32 }
4 d- ]' ^) _! m1 E/ e33 8 J% v. {4 i. ]: F) b( f& M2 n
34 void TEA::decrypt(const byte *in, byte *out) {
2 G$ Z% A& C$ A% A, V35 decrypt((const ulong*)in, (ulong*)out);
* W% l; d0 |& u4 ~. Q S' f36 } 9 g$ L' `' `* Z, i. J( _, M
37
& {: r c3 e5 g/ O( q1 m38 void TEA::encrypt(const ulong *in, ulong *out) { % E, }7 C9 [; Z& p- @. E
39 2 U1 Y( z6 w5 Q: B+ c1 M
40 ulong *k = (ulong*)_key;
m2 P4 `5 q; `3 r8 b3 x0 L4 O6 o41 register ulong y = ntoh(in[0]);
- Y0 I) J; o6 j1 C42 register ulong z = ntoh(in[1]); 9 \2 E0 z% v& e, ^# ?# u0 q- \0 E. S: s
43 register ulong a = ntoh(k[0]); 9 ^) O! Z9 `) i. o0 l3 F6 ~
44 register ulong b = ntoh(k[1]);
/ P0 z5 k' _! b/ z! Z45 register ulong c = ntoh(k[2]); 5 B6 |( K+ Y2 K" c
46 register ulong d = ntoh(k[3]);
}& [" R, o* J" C47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
0 v6 Y5 r' }" N7 \5 ~ w% s0 d: q48 register int round = _round;
0 q3 W0 q5 L0 W5 n! W49 register ulong sum = 0;
$ y9 |9 ]7 z# m; U1 N# ~8 e50 ( O6 e- W- K+ Z) a& W0 j! g
51 while (round--) { /* basic cycle start */
6 D, N7 y1 b- E% o, ?52 sum += delta; & Q/ d$ c* t) B6 b* D3 a' u) F" H
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); 4 l9 b5 r5 n* t- }8 \& @- n: v
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
( t) V8 C5 h* P& {5 l55 } /* end cycle */
/ Q7 a+ y& L! s# L' M3 F56 out[0] = ntoh(y);
( L% ~5 s/ W5 n0 @5 l7 e0 ~& w57 out[1] = ntoh(z);
/ i* n% ]) R. A3 k3 ~7 S58 }
8 ^, G$ d' t1 B. F5 W59 * B) T8 ^3 l+ G: o3 D2 d5 Z
60 void TEA::decrypt(const ulong *in, ulong *out) { - ]+ d# Y; A ]
61 / N6 B a- n: w+ A2 s; H4 w
62 ulong *k = (ulong*)_key; , `6 R9 j& O0 g7 w% M$ m
63 register ulong y = ntoh(in[0]); / j1 j) o* M I. x. C2 |, Z
64 register ulong z = ntoh(in[1]); 7 O) X, R( m- c/ a. V
65 register ulong a = ntoh(k[0]); " A; b5 H% C' H8 u* ?# G* ^
66 register ulong b = ntoh(k[1]); " s/ s1 {* `1 N# _4 E
67 register ulong c = ntoh(k[2]);
6 G/ ~: s2 m5 h: l, ~. Z" m' _1 _68 register ulong d = ntoh(k[3]); 7 o' e. I* \- B8 g; ?4 e7 t
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 3 l% o# T" d$ Q( e5 {
70 register int round = _round;
; g3 j. L5 B& s# i5 I! g71 register ulong sum = 0; * W% l7 s- F7 l6 l0 }
72
& q. l. J; l) A3 L+ Q3 Q; |73 if (round == 32)
2 E7 d8 n5 z6 W6 c6 N% T: J7 p' c74 sum = 0xC6EF3720; /* delta << 5*/
8 w. b2 `- O% n w& g. T* l: Z75 else if (round == 16) / a* T& o# o( g: @, c/ t! N w# o
76 sum = 0xE3779B90; /* delta << 4*/ + i8 ^% U1 d8 T
77 else % r; @4 |# _! O8 x. V7 X
78 sum = delta << static_cast<int>(logbase(2, round)); 3 |) y3 S" A3 V
79
9 V; `/ }6 _ ]+ M' B6 F80 while (round--) { /* basic cycle start */
$ w. l) I- T! O) N( O$ J' @81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
- }2 d% J( T2 D2 w/ u82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); ) D. [) K1 L' r6 ?* o" s
83 sum -= delta; / Z% j# {" _1 R" |
84 } /* end cycle */
. ?- \* ~+ H6 {+ g; @5 m; k85 out[0] = ntoh(y); + ?8 T# c3 H: ^' ^
86 out[1] = ntoh(z);
6 ^( m4 e2 T7 R0 T% w87 }6 y9 h) k! c: l; i4 D4 X" I
. O* F; @2 B' |) I0 r需要说明的是TEA的构造函数: - L% ]- I' q- [! ~
TEA(const byte *key, int round = 32, bool isNetByte = false); ) e7 I j" n% e$ L: z
1.key - 加密或解密用的128-bit(16byte)密钥。 ; P7 X1 W' E2 f, M
2.round - 加密或解密的轮数,常用的有64,32,16。 % d, U9 v, w; ~5 g
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! 8 W8 V5 T- L' i7 q' ]" x$ k
! q8 |$ g. ^. b& q
最后当然少不了测试代码: |
|