|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" _5 D2 U, g) {/ s
2 #include <cstring> //for memcpy,memset
6 y$ G+ Y. |4 D/ _( @ 3
I( s! _, y. S 4 using namespace std;
5 N: z" y8 D& `2 g) O 5
6 N9 ^2 [& ]+ _" z: I 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) % n8 d8 s+ U* w7 j4 t! D
7 :_round(round)
/ p4 n+ S- K* @' E/ m9 v; ?9 G 8 ,_isNetByte(isNetByte) { 7 s; Z1 a1 _5 y$ k1 ]! X9 ^7 b
9 if (key != 0)
5 r# \: z7 F, y. \: \9 L! }10 memcpy(_key, key, 16); 3 x( J; ^8 n, K& R
11 else $ c' r" }9 U! @' ^6 B& c
12 memset(_key, 0, 16); ( a; M7 P {* n" D! i8 C; Z8 A
13 }
) m J1 v, ?5 u* D* X& {# E14 9 _& S8 N/ Y; R* A3 V
15 TEA::TEA(const TEA &rhs)
* e( }& J# V' h/ Z& C16 :_round(rhs._round)
2 J |* u4 a1 Q0 R5 q, ?5 p# y& ]17 ,_isNetByte(rhs._isNetByte) {
e( h- J) Y( X6 D18 memcpy(_key, rhs._key, 16);
% R; v( y5 F3 X/ p6 z; K19 } # e7 u) y% D, z8 o6 r" _0 K4 a7 Z
20
+ C3 Q, M4 O' H0 v2 _* r21 TEA& TEA::operator=(const TEA &rhs) { ! i" Q! F' @" r8 R$ Y- r: O% \$ @' }
22 if (&rhs != this) { ' Y& T, q, B3 q% i# d. m( w: R
23 _round = rhs._round;
6 q& _* z5 U1 N9 J5 \; e$ ~2 I24 _isNetByte = rhs._isNetByte;
7 l% r! T! P) d% T( D25 memcpy(_key, rhs._key, 16);
$ ^# t/ H6 F; b8 g8 B4 Q& c26 } ( h1 ^: q: \# U2 }3 d ?
27 return *this;
0 W4 f+ ]; b" k' x28 }
0 ]$ i( h0 @, N$ H3 y/ G29 " b# L; w* W) d$ Z
30 void TEA::encrypt(const byte *in, byte *out) {
' w4 Q c) } r( O G. W31 encrypt((const ulong*)in, (ulong*)out);
0 B6 Y0 t& E. K- ~+ D32 }
- d O6 U2 M" i8 _' d33
: f9 [/ S: Z" }" x8 G' v34 void TEA::decrypt(const byte *in, byte *out) {
' a- R# J8 X* U35 decrypt((const ulong*)in, (ulong*)out); 8 y2 e$ N1 e& C+ h% k8 e" Q, D0 Y! Y
36 } $ |$ w+ R5 T, P: H: d& f$ m: f8 I
37
$ k. s! g2 g$ k# K ?- F: d; G( z38 void TEA::encrypt(const ulong *in, ulong *out) { 7 O" {1 z# @% a0 k2 g' R
39 # j1 P* \% x) ?7 P+ u
40 ulong *k = (ulong*)_key; 7 G; T# d" P) Z7 k; ~; B( ?/ K. Z
41 register ulong y = ntoh(in[0]); + m$ {, [7 S0 ~% C
42 register ulong z = ntoh(in[1]);
# a/ p: ?* J" w% k J3 E% ^43 register ulong a = ntoh(k[0]); 1 w, f3 t4 x, W& h# @
44 register ulong b = ntoh(k[1]);
, A% [/ }5 H9 s F$ {1 u45 register ulong c = ntoh(k[2]); 9 G# \/ q% S, B7 A" S0 s
46 register ulong d = ntoh(k[3]);
9 P h" |, W. [47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 1 U' D, g6 `& J
48 register int round = _round; ! d$ v( p3 b3 b( A
49 register ulong sum = 0;
2 t; z0 Z& k- o4 f& q3 z' h50 + O/ s j# y) d# E
51 while (round--) { /* basic cycle start */
6 l, l+ M$ {2 `) ?" ~/ [- `52 sum += delta; / F, V. s) W- @7 i- T4 i' k5 a q
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); 2 K; Q3 x9 @: x4 K% p$ r! s8 U
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); ' K: g0 S2 j9 O* f7 \# p
55 } /* end cycle */ $ a: f- l+ G. o1 v- z% L
56 out[0] = ntoh(y);
' N' r& @, m( m0 ]/ w4 |- v57 out[1] = ntoh(z); " Y1 V6 y# Q4 ? Y+ G
58 }
& I, n- D2 d7 u( C59 2 |2 t6 Q) b8 B! _0 p/ d! h) W' J
60 void TEA::decrypt(const ulong *in, ulong *out) {
* g3 v! }0 C- s$ R; _) B! n61
7 h0 D6 ?3 [) E Y( [# @62 ulong *k = (ulong*)_key; / H! Y7 J/ n0 l& Y8 U3 d' m. { }
63 register ulong y = ntoh(in[0]); % w6 y) Y6 a' A8 i2 s) H0 n
64 register ulong z = ntoh(in[1]);
; ?7 V* x/ }+ ^! y) S$ _65 register ulong a = ntoh(k[0]); . x# j- G5 Q* u" A% S3 D
66 register ulong b = ntoh(k[1]); & s3 l% Y$ T" c1 T
67 register ulong c = ntoh(k[2]); + ]- W* `/ q* ^, X* v1 N! c/ A/ s& F
68 register ulong d = ntoh(k[3]); 9 s) ~9 G! a* f; h: G; A; J% G
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
- y& a+ U4 ]6 D% F6 m* U70 register int round = _round;
: p& X: f2 d7 }/ f" X7 n71 register ulong sum = 0; 6 W2 S# W- n0 S" y
72
" C" }) J- I2 _% m73 if (round == 32)
# Z1 A( W9 u6 l! b' b6 Q F74 sum = 0xC6EF3720; /* delta << 5*/ 5 X! w# u0 J/ k' B
75 else if (round == 16) / c; c3 Y1 o8 Q% G. q- X, F3 h
76 sum = 0xE3779B90; /* delta << 4*/
0 r$ n1 k( r: ^( u) |77 else
1 k) e. s7 t* N$ j78 sum = delta << static_cast<int>(logbase(2, round));
( Q5 `6 _( _# F7 W* i79 , A7 H8 U# f/ Q3 R. W5 |
80 while (round--) { /* basic cycle start */ 2 \6 e: Q) e( }( l- O: I
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
t7 ]7 O" [' V4 }9 {82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
: p& c l. T7 I/ g3 N9 g83 sum -= delta;
# x5 A+ }- n* G84 } /* end cycle */ ( W7 B9 v& k6 H O0 W( {
85 out[0] = ntoh(y);
( k5 u3 D+ z z7 N7 f/ n* y& N$ w86 out[1] = ntoh(z);
/ J; V+ t \3 F3 S87 }
8 B- R) P1 ]9 f+ j) e' h! d2 x, N0 P- K3 ]2 C J6 |, H# r
需要说明的是TEA的构造函数:
8 ~. H* |5 c) N+ v( fTEA(const byte *key, int round = 32, bool isNetByte = false); 7 i5 o4 K- x" I/ v: S
1.key - 加密或解密用的128-bit(16byte)密钥。
8 M' J6 M% a L) ?0 x( F$ {2.round - 加密或解密的轮数,常用的有64,32,16。
& @2 H, |* F/ i3 s' q& J3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
( E0 u; `* p5 r0 f- I5 Z3 G* ^! w3 i: @$ @ w& n
最后当然少不了测试代码: |
|