|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
' |8 a2 p) k' c% ^* T$ [/ M+ L 2 #include <cstring> //for memcpy,memset 2 q `) ?# M2 B( F. K1 l/ |$ l
3
; W9 `4 B% v5 B% x# g 4 using namespace std; 6 m6 `; x9 y4 R& M, X3 ^
5
7 S4 P2 W7 w/ s& W0 T9 ` 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) ) p) {. G: O6 W/ m0 I3 h' y. V
7 :_round(round) ; U& E, D/ n' r: h6 |# i
8 ,_isNetByte(isNetByte) { 3 G/ P- _( L: L: c/ G7 O
9 if (key != 0) p3 F) e4 X# n2 t
10 memcpy(_key, key, 16); 4 p5 _8 \& H [% U5 f) p
11 else ) I. h, F5 C* a3 T
12 memset(_key, 0, 16); 5 C/ m/ j$ r* ]
13 } + C0 P. A. X6 A1 W ]$ k1 L
14 9 P' S [3 M3 \ i' f
15 TEA::TEA(const TEA &rhs) 6 E( U, l0 F: |% p& n4 c
16 :_round(rhs._round) 4 j, p+ x4 M+ |/ K0 j# i
17 ,_isNetByte(rhs._isNetByte) {
: t; Z0 e) k( z! d* J18 memcpy(_key, rhs._key, 16);
: S+ K2 \ m8 `9 ?# L19 }
/ l) E% w, }, y9 [20
& n+ J; o6 `$ ^( }* \9 O4 j21 TEA& TEA::operator=(const TEA &rhs) { : n3 @$ z. _* @3 Q \3 d
22 if (&rhs != this) { % x( |' A( w8 m% I( V( n
23 _round = rhs._round;
6 S1 C1 H; R; S1 O24 _isNetByte = rhs._isNetByte;
! M# \/ Z! }4 v& }25 memcpy(_key, rhs._key, 16); ! I1 C) G- ]6 U* A1 \' m
26 } ) [% w: ^0 G) ] \3 T
27 return *this;
9 o" \# k5 s2 e8 e1 }28 } 7 ~0 G9 Z, ~5 F) C/ s
29
8 N E* ~! i+ q- m8 x' }6 E9 K) G30 void TEA::encrypt(const byte *in, byte *out) { 9 t8 i8 C4 z' n9 g {
31 encrypt((const ulong*)in, (ulong*)out);
E" Q! t. ~7 B$ l32 }
" h8 i: X: W3 T6 J5 R0 d" @33
. X' g$ c$ P( g7 v: C1 Y34 void TEA::decrypt(const byte *in, byte *out) { & k4 k$ c! ~ O# k
35 decrypt((const ulong*)in, (ulong*)out);
# r# {* P; W2 V5 K+ \36 } + x ^; Y0 _5 ?" R3 I+ W, b
37 3 `- R4 V& X% D2 Z; Q h
38 void TEA::encrypt(const ulong *in, ulong *out) { 8 X0 P8 K; M7 w
39
- g" D/ |1 |) |% f1 q- z+ B( n40 ulong *k = (ulong*)_key;
. i7 P5 X! o* ~/ L41 register ulong y = ntoh(in[0]);
2 W4 a. `$ {$ I42 register ulong z = ntoh(in[1]);
P3 i! `8 G% R9 |8 w; M5 T/ {% y; j43 register ulong a = ntoh(k[0]); / B, o K7 p6 H' l: [) W& P; V
44 register ulong b = ntoh(k[1]); 0 M5 P# w2 w9 N. t* S
45 register ulong c = ntoh(k[2]); 9 j8 r8 |9 @! ^+ D7 Z& C* X
46 register ulong d = ntoh(k[3]);
6 i5 h- M' @8 K8 N47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ * ?! q" k6 Y- W5 ~. J
48 register int round = _round; " U9 H9 Y& o5 z0 C" I( B
49 register ulong sum = 0;
% [1 V# ~% b- F3 q B50
$ A/ o& Q/ E; O' D0 R6 Q51 while (round--) { /* basic cycle start */ 2 R% \' E* f& }+ T2 \+ |
52 sum += delta;
' U' Z1 ~+ {9 {53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); + ^9 G1 p/ h2 T8 g- n! h
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); / S/ S) M; D/ Y2 v
55 } /* end cycle */
f$ h' y, u4 _, e$ a4 g56 out[0] = ntoh(y);
9 v+ }' A' V n* m9 ^) E57 out[1] = ntoh(z);
+ {7 }) {% K% [( K4 P6 W58 } 9 ^6 g, d* f' ]9 r3 y
59 , ? r8 z3 u& M1 A7 z. K2 s
60 void TEA::decrypt(const ulong *in, ulong *out) { 1 X; r3 {" h% r
61
" V6 D j' H$ K+ L( D, P62 ulong *k = (ulong*)_key; 6 j5 @3 x [( E9 e1 y t
63 register ulong y = ntoh(in[0]);
9 S2 g! l2 I6 i3 H, P64 register ulong z = ntoh(in[1]);
, L9 `1 y) \; j7 M65 register ulong a = ntoh(k[0]); + C% E, z$ A3 H+ j8 N
66 register ulong b = ntoh(k[1]); # }' R, J* l7 G5 U; L% Q+ g- V
67 register ulong c = ntoh(k[2]);
! L$ m4 }% u9 Y2 g2 ^3 k68 register ulong d = ntoh(k[3]); 0 x& m: H. _4 ~& g _! n
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
: g* {% T I# R/ p+ }( i9 [70 register int round = _round;
: b1 K& {+ o0 Y4 s71 register ulong sum = 0;
+ R+ [6 E" Y9 f5 V72
* W0 i5 d- H g5 B8 _( V( {3 t: i73 if (round == 32) % R+ }$ z4 e+ E$ [. x/ B
74 sum = 0xC6EF3720; /* delta << 5*/
7 E. b# L* q& O9 v Z75 else if (round == 16)
3 p7 e3 f/ |( t76 sum = 0xE3779B90; /* delta << 4*/
# K m- `) I j8 A6 _/ h: y77 else / c. Z, M, o, c \
78 sum = delta << static_cast<int>(logbase(2, round)); / E* i) f/ w4 J& H! ?- Q
79 . E3 j2 ~: Q$ B6 X
80 while (round--) { /* basic cycle start */
0 S0 H. N- T" U6 P9 r; d8 m/ f81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); & u3 J" h& q5 P, d) j: l
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); $ ]6 T/ V6 e) R# J% U7 c8 N
83 sum -= delta; 4 J9 s$ N. Q) W9 r
84 } /* end cycle */
& P+ E6 }$ G$ F( |85 out[0] = ntoh(y);
9 y0 d: M) S: E3 ?& A86 out[1] = ntoh(z);
1 a" ^4 d' R8 S+ [87 }
/ R% Q; j# O* B) ^
/ a/ Q/ B' L3 t, n- [) Q( ?需要说明的是TEA的构造函数:
0 R) E+ }# U* U# J$ b6 T) oTEA(const byte *key, int round = 32, bool isNetByte = false);
, P& Z% G9 H9 W- O5 a" A1.key - 加密或解密用的128-bit(16byte)密钥。 6 ?# Q" M8 a1 g
2.round - 加密或解密的轮数,常用的有64,32,16。
/ @$ p& N" i6 a5 r L4 M( ]4 ]0 O3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! - c: t J; B7 h, E1 r* R) j
4 g, u6 ~; V/ k! J9 K最后当然少不了测试代码: |
|