|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
7 O, V& p5 j3 s7 m) { 2 #include <cstring> //for memcpy,memset 7 J v- I0 B) N
3 ! G, q* }4 `! @, I
4 using namespace std;
# w( K5 H" W4 S* [ 5
C1 W8 a, E# e6 c& g! y7 b# F/ P 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
! g: F7 _( Z+ v! g" M; \ 7 :_round(round)
* W' H) W! j1 k! u. ]. z2 W' f/ X 8 ,_isNetByte(isNetByte) {
, G" u; Q% P. e0 c 9 if (key != 0)
3 U' A0 S. l' p. ~6 f10 memcpy(_key, key, 16);
; M* J0 A* F( u: s11 else % ~: Z2 J' ?7 } f& X {
12 memset(_key, 0, 16);
" K7 N6 \+ l Y3 V4 o2 t13 } 4 B# h! u H- B Q* l
14 9 |7 B6 ]% B7 J; C1 }
15 TEA::TEA(const TEA &rhs) 3 r4 x( l9 _ q: V2 [3 W
16 :_round(rhs._round)
$ _9 p& t" p; t5 F& H17 ,_isNetByte(rhs._isNetByte) {
2 P+ l+ t. N0 `, t18 memcpy(_key, rhs._key, 16); 5 G9 d- e. |# Q& U
19 }
& E* j/ I! K! R20 # B: O6 K, R: ]/ U2 i+ z0 _
21 TEA& TEA::operator=(const TEA &rhs) {
4 G" d! n! ]- t7 i22 if (&rhs != this) { 0 g; y9 Q3 `* ]" t' [/ j+ S! l
23 _round = rhs._round;
8 W& o% o/ I) C8 O24 _isNetByte = rhs._isNetByte;
8 _0 R8 c. z3 ~ m25 memcpy(_key, rhs._key, 16); / z5 _3 P: a2 m% Q3 ?
26 }
7 t) f1 x$ i7 a$ X* z$ W27 return *this; 5 l% I" }. l& ?5 D( O
28 } " b( h K9 O2 Z R# ^
29 - K& \2 F$ Y# I h5 p9 r, j
30 void TEA::encrypt(const byte *in, byte *out) {
, v$ ^! H# y. t2 {* \3 `31 encrypt((const ulong*)in, (ulong*)out); ( c2 a0 E! j. e* ~( B
32 } : z5 H: A1 f2 \
33
3 E7 h( |$ ^0 U' @ v! R: x0 d: y y34 void TEA::decrypt(const byte *in, byte *out) { : H/ r2 u# T+ @/ i4 f, l) k
35 decrypt((const ulong*)in, (ulong*)out); : ]: I% Z" q6 R9 p- ?0 V
36 }
% c$ d, l8 d2 z5 S37
( t0 t5 @" r5 Q9 D2 I8 S" U38 void TEA::encrypt(const ulong *in, ulong *out) {
) y( D- S5 s" l) J/ y39 l- ]! v2 D" k9 |
40 ulong *k = (ulong*)_key;
: ]0 s" L3 O# ~$ Z9 d# S! P; a41 register ulong y = ntoh(in[0]); % w8 i5 ~0 D, Z N
42 register ulong z = ntoh(in[1]);
& |1 G- l4 P+ x: q( b43 register ulong a = ntoh(k[0]);
# D7 l- d& r* n- j" h# V6 w44 register ulong b = ntoh(k[1]); " X3 v; H! Y( _
45 register ulong c = ntoh(k[2]);
' ^# W9 @3 j+ K8 C1 v' M46 register ulong d = ntoh(k[3]);
Q+ b- l8 l/ l" _% c5 D0 @ V! e47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
; }/ I$ E9 w3 h: p( e! J48 register int round = _round; 8 R2 ]& V) {$ i" x* W! l
49 register ulong sum = 0;
1 Z, p$ X3 u3 Z9 i* N3 R50
& I6 ?; P. f0 x6 _8 y51 while (round--) { /* basic cycle start */
" |, j. @* r2 S52 sum += delta; # L" b5 B" f5 I
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
; e# |8 b1 J) d& Y; Y9 e54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); : ]8 M' j- N6 _, V$ p* g5 G
55 } /* end cycle */
' r: S- Y5 y' h% S; O6 t. Z* g56 out[0] = ntoh(y);
" k2 i* k! K* L57 out[1] = ntoh(z); 1 H4 b1 _3 k6 X
58 }
I) Z5 a( z: h) M$ B2 R: F59 w" s" j' w" q- ]8 ]
60 void TEA::decrypt(const ulong *in, ulong *out) {
8 u( }$ C! _) y# u! J61
' b% M/ `( {) k( u" P* {0 ^62 ulong *k = (ulong*)_key; # y5 N( e+ S- H) b) l2 ^1 R
63 register ulong y = ntoh(in[0]);
$ K$ u1 B' s+ V0 v7 E64 register ulong z = ntoh(in[1]);
4 M+ T2 Z, i& m( X65 register ulong a = ntoh(k[0]);
, M, ?+ |; S4 e i66 register ulong b = ntoh(k[1]);
& x7 `1 U4 _9 e67 register ulong c = ntoh(k[2]);
/ ?5 d2 `4 N2 l1 [1 p! \68 register ulong d = ntoh(k[3]); . L6 W2 e8 H( l9 |2 M# P
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 5 ~: j4 t" h2 G1 A
70 register int round = _round; - V* U2 E- ^& V( k) ]$ m0 m J
71 register ulong sum = 0;
& R8 X! r; L' p* J, w5 A72 1 C7 l ?1 t5 q, r. F2 Q
73 if (round == 32) _0 @; h( I1 A y% b* {
74 sum = 0xC6EF3720; /* delta << 5*/
' f" |& N1 k* Y1 k75 else if (round == 16) . @3 F/ \, X$ _) p8 e$ F3 ~# V
76 sum = 0xE3779B90; /* delta << 4*/
( n- m, [% a, }9 U9 Z77 else + o; n' f" t+ j+ S
78 sum = delta << static_cast<int>(logbase(2, round)); 1 z) k( r% g. _+ @3 _2 {
79 6 i! T9 h/ p' ^' B% Y; \0 R9 t9 {
80 while (round--) { /* basic cycle start */ 1 z) _3 `* i- j1 t B! A
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
; }1 l0 E, f+ Z4 g t% {5 u$ K) _82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
% Y2 k v9 ?9 q83 sum -= delta; 5 q3 e( Y+ p) x: K* q
84 } /* end cycle */ 0 m0 x/ d& a9 u9 @, r
85 out[0] = ntoh(y); ) ]. Z: `; M/ @# S" G5 b
86 out[1] = ntoh(z);
. ]1 O9 l6 e. i5 c# h; V" s87 }8 e. W r; N) d4 ]' o
" i& R( x$ l, @7 R) d/ f
需要说明的是TEA的构造函数:
# \% T b' C- s/ I/ N* ^4 o: tTEA(const byte *key, int round = 32, bool isNetByte = false); - d" H) N7 ?" w4 e* @
1.key - 加密或解密用的128-bit(16byte)密钥。 - r% e0 I( a7 ^2 z6 p( H/ b
2.round - 加密或解密的轮数,常用的有64,32,16。 3 I9 q/ ]( ~ A# P- @: @+ \
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
* w# i" ~2 h' A! E- t: l
0 w1 l s! s/ R8 ~; J- v最后当然少不了测试代码: |
|