|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
1 s) c* S9 S2 Z. a 2 #include <cstring> //for memcpy,memset
# r0 ^' ~/ T d 3 ; [; C; x. i, ]6 X# \* K" t: R$ B
4 using namespace std;
" ^; O( c- k4 l9 [3 R 5 / g. U9 p( |$ |. H6 f
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) # U, a i) Y; E) ^
7 :_round(round)
6 P: v8 N4 {$ G/ B3 C 8 ,_isNetByte(isNetByte) { # H/ L6 y( @4 _0 u
9 if (key != 0) : [2 a; n1 o$ ~. M0 C# v
10 memcpy(_key, key, 16);
* I# g* n: f/ B9 b: \, c11 else ! P2 o0 L& T- L* D
12 memset(_key, 0, 16); 8 d" h6 i j& K
13 } ) q/ R9 t l+ a1 s6 f/ E0 B3 T
14
$ b8 Q: Y& ? ?. G' z# L15 TEA::TEA(const TEA &rhs)
4 V5 l. j5 v( ]- v9 D! @ Z7 a16 :_round(rhs._round)
! D7 Y/ j& k4 o% w2 y2 G6 T& G17 ,_isNetByte(rhs._isNetByte) {
& B+ p; h: ^+ x, {! j T18 memcpy(_key, rhs._key, 16); / d# t8 k6 n& e
19 }
" Y# _5 x R+ x b20 # L) v% p4 M6 o6 }
21 TEA& TEA::operator=(const TEA &rhs) { $ w5 ^2 b$ D: W. ~" D
22 if (&rhs != this) { ' x1 W* v; @4 D5 s" z
23 _round = rhs._round;
6 b$ l8 G3 i% }7 z W+ N) y24 _isNetByte = rhs._isNetByte; ( p' n- m) a2 B& j; _0 Y# R( Y
25 memcpy(_key, rhs._key, 16); ' O& h4 a* `7 z, {
26 } 5 L! t, u, W3 M& Y! |+ q; _
27 return *this;
$ \; r j6 @4 a* h1 ^* a28 }
z4 \4 J4 X! z T7 B8 c7 f9 e1 T0 \29
& f( Y: E# R1 j$ D30 void TEA::encrypt(const byte *in, byte *out) {
" T2 J# j+ U$ z; X9 n1 M31 encrypt((const ulong*)in, (ulong*)out); 1 [" f$ z1 r! h H
32 }
0 }' N) T$ P9 ]7 o- j( m33 & [0 }! Y8 d- q- @# n
34 void TEA::decrypt(const byte *in, byte *out) {
' r! |8 I4 O( P8 x* _35 decrypt((const ulong*)in, (ulong*)out);
6 L* H, |8 T: W4 s/ f- j8 D+ M36 } 8 U- V9 k$ a1 l3 B. D1 }
37
8 O2 \6 {' ?/ f- j38 void TEA::encrypt(const ulong *in, ulong *out) { 5 J& M' u" n( q$ ^' B5 t) O' [
39
* `1 d4 Z6 Z+ z, e# h/ u40 ulong *k = (ulong*)_key;
1 x. x& N8 a$ I8 m: N& j41 register ulong y = ntoh(in[0]);
0 h& h" X7 E% s42 register ulong z = ntoh(in[1]); & d+ B( N: `/ K/ E I. o" O% Q% s
43 register ulong a = ntoh(k[0]);
. `, O0 Z" w, _) H% n44 register ulong b = ntoh(k[1]);
( H) W# K" b/ i# D# y- A" F45 register ulong c = ntoh(k[2]);
F4 L; i: ]& }, o46 register ulong d = ntoh(k[3]);
( A8 J! J! f" t- V47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
. b, h p, N6 r48 register int round = _round;
% B2 t, u7 Y1 N49 register ulong sum = 0;
; J" P' G9 z* [7 K+ E2 g8 U50 d: Z! u3 m8 o6 E+ V& D4 v
51 while (round--) { /* basic cycle start */
4 o# x: c) h0 W9 T) g# ]) x52 sum += delta; 5 ]6 s( y. ^; o$ q! i$ A! E
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
! }3 Z2 Z, w, k; n( o. G1 Q. l# A54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); 3 q4 R8 ~# h. E0 B% B n
55 } /* end cycle */ % q: f# z# X" d
56 out[0] = ntoh(y); 9 n/ r" \4 }4 Q/ m* Z
57 out[1] = ntoh(z);
; D0 k6 d! Z8 X; n& S( I58 }
+ o! W" g0 ^! F0 ~" H' E# q- P w59
6 M3 F" ]3 x7 M2 [7 V60 void TEA::decrypt(const ulong *in, ulong *out) { 4 f2 |1 a4 {3 h" x7 b( G4 S5 w
61
+ X' L0 `7 J" F& C5 Y- X( b& ^; M62 ulong *k = (ulong*)_key;
) U, l% Z: M' P* @63 register ulong y = ntoh(in[0]); ! Z, t1 b( r( X+ S, m( K- g+ F
64 register ulong z = ntoh(in[1]);
, F1 y* N' O4 C" H! u. A65 register ulong a = ntoh(k[0]);
+ b5 l, n$ s. ]( |0 m$ a) C66 register ulong b = ntoh(k[1]); . d# U. B% Z. u' b
67 register ulong c = ntoh(k[2]); 3 e, S4 H4 H& ]0 q/ X
68 register ulong d = ntoh(k[3]); 7 w) U, ~+ c# T5 U# j% |1 B U; a3 T
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
9 M) t O& c1 ]; P# { ]3 ]70 register int round = _round;
" w* j% h) k, L1 o; y1 @71 register ulong sum = 0;
- z' y# e6 [6 a- U+ b' @+ V0 {7 w72 $ ?/ [7 G' }$ ~
73 if (round == 32) & Q" ^1 c9 R k8 g, X, o& f
74 sum = 0xC6EF3720; /* delta << 5*/
+ M; N9 k7 G$ `" `1 i! G* E75 else if (round == 16) % x" m8 V+ f( M+ U( U
76 sum = 0xE3779B90; /* delta << 4*/
: O2 w! o, H; c* x1 b1 O0 i! ]77 else * E$ R9 i0 ^! c. s
78 sum = delta << static_cast<int>(logbase(2, round)); 8 j2 [9 G; T" B- f$ f( ^( o, j q
79
$ Z1 ^- c: |% m" S; ?80 while (round--) { /* basic cycle start */
' {3 B% h' t& P7 U81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); 6 l: D. U- i2 R
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
& i9 v- B: V% J$ ~( a* X) X# i83 sum -= delta; , j; f3 \) f z+ P
84 } /* end cycle */
o8 x" z1 Y, @) P. }85 out[0] = ntoh(y); , i, P/ i, T9 ?) V5 D" Y: F$ ]6 k
86 out[1] = ntoh(z);
: ^" t, L* |. `+ ], Y+ ~87 }
9 ~( Y; l- A1 R/ N6 d6 J! k( C
, Z% x+ \* a+ e8 f& R4 }需要说明的是TEA的构造函数: 7 k. T% A$ V/ u, s* X- a! C
TEA(const byte *key, int round = 32, bool isNetByte = false); " {+ P) k8 O( S4 ?
1.key - 加密或解密用的128-bit(16byte)密钥。
9 A8 r- u0 W( }# \2.round - 加密或解密的轮数,常用的有64,32,16。
0 ?& S7 v6 d3 H6 }5 g3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
; n( u2 I1 m4 F7 a; B% J9 V. Z& A' p
最后当然少不了测试代码: |
|