|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" # O- S- A4 o8 p }, `1 G! f" w4 O
2 #include <cstring> //for memcpy,memset 5 R/ |9 U+ Z! ~3 b1 d
3
/ T+ N0 I- W; J1 @3 H% U 4 using namespace std;
+ g, H' t- B3 ^* `/ o 5 . ~" @8 s$ ~# o6 F7 X! F+ ^
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) 8 x: E6 \1 S5 G; j
7 :_round(round) ; g* m$ ?7 v* Q. G" u9 U$ H
8 ,_isNetByte(isNetByte) { 5 r/ d; v2 f# d0 n
9 if (key != 0) 1 O% ?* _2 v% `8 I2 n
10 memcpy(_key, key, 16);
3 } y7 G/ r2 w( d0 c% a. r8 H11 else ; I! F7 Q; C- G5 ?5 Z7 Y* X
12 memset(_key, 0, 16); 3 Z3 ~4 O9 D- ~# J. D
13 } 8 V; b! y! Z+ a) O/ t( x
14 8 e- O0 m2 Q$ q2 q) J
15 TEA::TEA(const TEA &rhs) : U7 E9 Z) E5 v, a# n" q
16 :_round(rhs._round)
8 u: a) b% b* X2 f% o3 q0 l$ }2 v8 h17 ,_isNetByte(rhs._isNetByte) {
$ @" [, `7 J8 h. P9 y$ U18 memcpy(_key, rhs._key, 16); 8 A! B( |! _7 Z/ e' M6 V% t& y! s
19 }
4 E2 I+ ^6 I. z3 \6 ?) r20 % ?% L8 N4 w8 H8 [' U: v* _! u# V
21 TEA& TEA::operator=(const TEA &rhs) {
/ M- H% p2 ~+ a6 U+ |2 w: A22 if (&rhs != this) { ; V, \% j( J7 k
23 _round = rhs._round;
3 w- R' F4 q O( D, G24 _isNetByte = rhs._isNetByte;
% R1 o0 ]& |# }& N25 memcpy(_key, rhs._key, 16);
* G4 s( J" h3 U/ m26 } & X+ t. u* w, ]
27 return *this;
5 {$ a3 _ R+ h) m. b/ D28 } * C7 S; U4 h2 |" Z8 L( I
29 - \$ s, i7 C& t9 w
30 void TEA::encrypt(const byte *in, byte *out) {
1 l+ N4 ^& g# u31 encrypt((const ulong*)in, (ulong*)out);
# G1 s( z: P4 F' O6 N- I* t32 }
: _* A9 ]- V9 e; C6 R% K33
2 Y/ b4 f$ z8 @. a34 void TEA::decrypt(const byte *in, byte *out) {
- O+ z: r' @5 @1 J8 e: }35 decrypt((const ulong*)in, (ulong*)out); + D: ` f9 G% T8 W8 D
36 } % K7 b* h( b3 a3 z! g9 G! r
37 . {, |' _3 L, k$ ?
38 void TEA::encrypt(const ulong *in, ulong *out) { ! @; V' c3 S2 r8 r
39
/ p( x& G4 J8 q( y. B. O+ A40 ulong *k = (ulong*)_key; - W7 _- o3 o$ ^9 ?5 b
41 register ulong y = ntoh(in[0]);
$ a7 P9 \2 h+ e8 {4 g R42 register ulong z = ntoh(in[1]); ' p; j( [4 D# B- @1 d* W1 w m, B
43 register ulong a = ntoh(k[0]); ) V, }+ m& v9 m# H: S' X' v# l; I
44 register ulong b = ntoh(k[1]);
( v( Z9 F: I6 d' r3 ^; V45 register ulong c = ntoh(k[2]);
2 J" ~" U6 A$ f- Q8 Z" A6 V46 register ulong d = ntoh(k[3]);
G8 x9 Q" L' a `! T' i; o47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ " I4 k" y, e. c! R7 ~! y8 K' H+ {
48 register int round = _round; x3 z( y h2 ^2 ?0 x$ \
49 register ulong sum = 0; 5 @" ]5 p/ E1 s# ]
50 " @, _$ t) y! B5 H: _& { U
51 while (round--) { /* basic cycle start */
4 s/ h! x% w3 r$ T52 sum += delta; 5 \) \, D! J/ l; X8 y; G9 D
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); 7 [6 ^+ }$ a8 h% s. o A. i+ R. z
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); # E& J) e; q# j; h
55 } /* end cycle */ . ]0 M# @6 m) X
56 out[0] = ntoh(y);
! b3 R, ? D5 _$ ?* I5 z& w5 D57 out[1] = ntoh(z);
+ O* ?' H/ `" X; Z" n58 } , ~* h+ W0 f+ V
59
+ q5 t8 V3 r0 N" v- N, l- ~- `9 @60 void TEA::decrypt(const ulong *in, ulong *out) { " j5 ]- b" y2 u7 p
61 5 O9 d9 O& Q- ~6 Q
62 ulong *k = (ulong*)_key;
) l) g; i( s; q1 O/ S63 register ulong y = ntoh(in[0]); # ^/ x% y% |& f1 r2 }; F
64 register ulong z = ntoh(in[1]); , n+ u' }$ @2 w* S( { I
65 register ulong a = ntoh(k[0]); " W' I1 Z& i: ^
66 register ulong b = ntoh(k[1]); $ y, B) t! [, g
67 register ulong c = ntoh(k[2]); , T5 W0 H' i+ u X/ O
68 register ulong d = ntoh(k[3]); 4 s* h; @. |: l. V
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
- M7 r; V3 s- q4 b2 y. k. m70 register int round = _round; J7 c* ^! s) u/ f5 Y
71 register ulong sum = 0;
, Q$ K' o) C1 e( _9 S1 p. J72
* F$ N5 f, X1 ?+ p% P/ |73 if (round == 32)
9 _" {! y, y0 v9 s5 X7 V' j9 V6 N! Q74 sum = 0xC6EF3720; /* delta << 5*/ # v) [' h) x4 t; R% {
75 else if (round == 16)
8 ]/ b8 X+ l! {3 s! s2 ], C76 sum = 0xE3779B90; /* delta << 4*/
; ^: w# Y' z' p% x: g$ Z77 else
+ j& x- d: G# R7 k; F0 D h+ @' u78 sum = delta << static_cast<int>(logbase(2, round));
+ N" Y4 Q. O" w% d( o79 , E( g3 r1 O1 w. j" J! e4 e
80 while (round--) { /* basic cycle start */ ( o' u: {/ x+ R2 a H/ P
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
1 E% S; U( ~: S, t$ E8 ?* w8 v7 E82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); 9 }, b6 V) _! c" }) a3 k4 ^$ z
83 sum -= delta; ) S: U1 G) r- v7 P9 Z3 k
84 } /* end cycle */
$ A8 y8 B& }8 D& i85 out[0] = ntoh(y); + b, f. Y0 k! }: @/ y6 m4 I
86 out[1] = ntoh(z);
! f; l7 Z+ V, z, u6 W87 }
& A- Q; ^7 Q! t6 k4 u: a( V% M8 y3 I5 B$ P7 v2 r* Y
需要说明的是TEA的构造函数: 7 L+ T3 {* }9 \$ K# M1 _, Z
TEA(const byte *key, int round = 32, bool isNetByte = false);
% q% }' T% C9 B9 w0 b1.key - 加密或解密用的128-bit(16byte)密钥。
; t/ ~, I8 r% o- G7 P9 E2.round - 加密或解密的轮数,常用的有64,32,16。
' W$ i. U$ g" y9 z* z H3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
3 Q& s: W7 t2 G: t$ }* Q& _2 k. d* @ o" l3 g/ J" x
最后当然少不了测试代码: |
|