|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" ; x; w8 h7 v- L e: e+ W* a! N# t
2 #include <cstring> //for memcpy,memset
0 l% T: P/ Q2 e" X: `& S; V 3
1 e$ Z/ u2 @! G( N8 P 4 using namespace std; # I/ i! s: [2 I( z5 X
5
! o+ s* [% Z6 L. K' w: n% S, n 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) 4 Q2 b9 ]3 {& N/ D# u
7 :_round(round) % I+ }- X: }) _9 A! z% ^% G
8 ,_isNetByte(isNetByte) { 4 R W/ M/ `0 S
9 if (key != 0) - V" \2 v$ w8 y9 X$ j8 Y* p I
10 memcpy(_key, key, 16); - V5 M! q7 c' E) d/ Q" y* ^, }. v
11 else
/ ^$ r/ Z; [! n6 ` D% p12 memset(_key, 0, 16);
% d& h# t+ l# c% D13 } 7 G. |0 b) |* Q: R. L
14 5 s6 q9 P" g/ @& F J
15 TEA::TEA(const TEA &rhs) 4 U; y) p+ i) O) ?& I; z8 e- ? y9 q
16 :_round(rhs._round) * C7 Z+ k4 M* p; i! [
17 ,_isNetByte(rhs._isNetByte) {
1 v2 ~/ r& g" C18 memcpy(_key, rhs._key, 16);
: ]; x( r5 v( }: n1 y19 }
6 I. v; u9 h0 S2 F8 L3 e20
- Y* ?- \+ q. C- Z21 TEA& TEA::operator=(const TEA &rhs) {
9 k8 |4 x3 R) X& C* @; \& p9 }22 if (&rhs != this) { 3 n% |/ d. Z; B- x. K
23 _round = rhs._round; 4 S3 I! j" R3 e2 `; S5 _
24 _isNetByte = rhs._isNetByte;
) \, _! w/ W7 Z8 [7 x9 ?( N; |25 memcpy(_key, rhs._key, 16);
( ?7 l' K* u8 h8 S. [, F26 }
/ J! O% b* r* R# {& J/ Y) Y27 return *this; 1 p3 }- j, c2 R- U$ H* Z4 W! S
28 } 5 k9 u0 j0 x9 I* Q
29
, v. d. W; q2 ^2 F. S# C30 void TEA::encrypt(const byte *in, byte *out) { 5 H- p; c4 l4 V5 m0 D) D
31 encrypt((const ulong*)in, (ulong*)out); . C E6 V) G$ ^9 W- K# U9 }
32 }
7 r& Y. K, B, _ p33
! B) L6 ?) T+ {34 void TEA::decrypt(const byte *in, byte *out) { 7 d, _# ]' [7 Y2 r! A9 I$ F
35 decrypt((const ulong*)in, (ulong*)out);
" ]" y" @! ` i, d" E% f36 }
7 i. K N! u, t* K; C7 r x1 T# T37 % o0 n) u4 C; H% m
38 void TEA::encrypt(const ulong *in, ulong *out) {
, U7 b0 U2 @8 L% ?) j39 6 U$ Z# {9 L- {1 K
40 ulong *k = (ulong*)_key; 5 `) [6 x- }4 S8 N* q# w
41 register ulong y = ntoh(in[0]); " g3 r8 t/ E* `; v2 a, T+ D8 L1 Z
42 register ulong z = ntoh(in[1]);
: W: y( _! w: m4 H) ~; G5 |3 |43 register ulong a = ntoh(k[0]); 6 X ?0 b4 u+ F
44 register ulong b = ntoh(k[1]);
$ P* p: j& x1 i( E! t+ D. _45 register ulong c = ntoh(k[2]); + Z* C# y7 E3 Q* A
46 register ulong d = ntoh(k[3]);
& Q/ U( B1 B9 ]" S47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ * C. z8 N1 ?- q4 I$ M
48 register int round = _round; : j& p C- \. N" H
49 register ulong sum = 0;
& R) C5 N: _4 _+ L8 J50
- F# B8 \* s4 H5 v/ ~51 while (round--) { /* basic cycle start */
8 m& n Q+ `. G9 v! B52 sum += delta;
`. S! Y. _, G+ A- T5 D53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); . N$ f, C. r3 H J9 _
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); ' B+ b, @" W$ a. A$ H% \0 n
55 } /* end cycle */
' f' E' D8 D5 u9 v56 out[0] = ntoh(y); + V5 V; Q. s6 M; l6 J' i* X
57 out[1] = ntoh(z); , y# `! I% Z0 o4 u$ N+ _3 @
58 }
/ g9 _8 F5 E# G59
e* |6 I8 l: g- |% a" x60 void TEA::decrypt(const ulong *in, ulong *out) {
, `" P: c6 }. q( F8 A61
; s/ f5 j7 y% k& ~3 m4 N5 \62 ulong *k = (ulong*)_key;
- Z- D) @' e. q) d63 register ulong y = ntoh(in[0]);
+ g2 E" E$ h3 M: j64 register ulong z = ntoh(in[1]); ( O3 J4 {4 ?+ s$ Y3 d: X8 V
65 register ulong a = ntoh(k[0]);
; n( M. \9 B" `66 register ulong b = ntoh(k[1]);
; J8 s3 C) ]* s; { t( w+ d! ]67 register ulong c = ntoh(k[2]); $ ~0 C+ k: ~0 Y. y; @% u
68 register ulong d = ntoh(k[3]); 5 P0 n& }% J. f5 R8 N0 I2 G" q4 u
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ ( a. ?9 c# k, R
70 register int round = _round;
. O; F% |. O; z+ n Z: O71 register ulong sum = 0;
6 n2 t' l! }1 W& N8 X7 m72 ' s; i7 h6 [' {
73 if (round == 32)
U# X8 H% v/ S! u74 sum = 0xC6EF3720; /* delta << 5*/
9 o* e z7 V& F( v6 |75 else if (round == 16)
3 M; U' d# T8 A" v$ W76 sum = 0xE3779B90; /* delta << 4*/
4 d" u M, ]+ [8 \$ e9 {77 else
& P1 R9 W) x. F% Y78 sum = delta << static_cast<int>(logbase(2, round)); ; y3 [& ? C6 X& ~8 t
79
+ `' C3 l& H8 ]7 D; c80 while (round--) { /* basic cycle start */
2 ~2 Z8 Y+ V) B: S' X) u+ \4 L/ m81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); ' {& j& f6 u* o6 m: { `+ P& H
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); , x$ R& |, n; D' i
83 sum -= delta;
( O" J- ?8 w/ K7 }5 k# ]84 } /* end cycle */ 3 j) x9 l8 I7 K$ e+ I5 p) j
85 out[0] = ntoh(y);
# A: @9 ?/ m$ x) H4 J7 {86 out[1] = ntoh(z);
) x: C- f: l5 A: [4 M4 B87 }" C; z# }6 J6 Q" o( E. r/ c$ u
/ s0 i/ w2 y B6 V* n1 K% Z7 m需要说明的是TEA的构造函数: $ T$ E& C8 R1 I4 w; ~4 P- s) O" n; ^
TEA(const byte *key, int round = 32, bool isNetByte = false); & O/ Z# G3 ~* G/ K* v1 [) ^
1.key - 加密或解密用的128-bit(16byte)密钥。
1 s8 F& S5 O( \! {% ^7 e! O; e3 X2.round - 加密或解密的轮数,常用的有64,32,16。 ! ?; e; x8 B' b: |
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! 1 F) W8 }( J0 z6 C: Q& u
' \/ l7 s4 I' m. l$ O' e& v0 ~最后当然少不了测试代码: |
|