|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
: {/ d3 c9 m. N. j8 \& i, }3 n' U' r 2 #include <cstring> //for memcpy,memset
9 Y* E- b/ |7 |& ~ w+ v* X 3
; m4 L) p' G+ N: J: V 4 using namespace std; : u+ x& Q4 F# }( J: `
5 . Y e( W9 W+ h
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
! S# w: J4 I4 ^8 D/ i) S 7 :_round(round) / U+ J# y! a3 h/ K( }
8 ,_isNetByte(isNetByte) { 1 b& m8 [0 c `9 J
9 if (key != 0) ' `! q4 q9 _' H. U4 Q
10 memcpy(_key, key, 16);
2 g1 Q! M3 h( V. G11 else
- J5 V! k% @- j- @12 memset(_key, 0, 16); 3 L' d8 s, U$ d6 O, Y
13 }
& V9 y" ~# j# f6 F9 j14
7 }8 M6 j: `5 u1 F* ?15 TEA::TEA(const TEA &rhs) 2 d. F! n9 K. R1 j- y8 L: |- ?
16 :_round(rhs._round) - k0 I& y" r) u0 s
17 ,_isNetByte(rhs._isNetByte) { , U; z2 {( P% i0 Z2 h5 x
18 memcpy(_key, rhs._key, 16); / D0 b% V% b- g B/ B( ~
19 } " y: v6 a% j" Y* n4 p
20
. w1 p1 U' g+ U8 x4 B" W* i21 TEA& TEA::operator=(const TEA &rhs) { 5 R t- l+ ~/ f; u' x
22 if (&rhs != this) {
9 d1 f# N2 y/ f* Q; G! g23 _round = rhs._round; ! [( x* q1 P9 x, b
24 _isNetByte = rhs._isNetByte;
! D! J q* S& y25 memcpy(_key, rhs._key, 16); $ k7 c% ? P! d0 i0 c
26 } * o7 U6 u8 s# x, a9 ]$ I# L4 O- a4 Y
27 return *this; + @& m( [8 d+ T
28 }
8 {! ~2 \, p, W. X& g' F29 9 [" h! w7 G8 o# b2 z" Z0 d
30 void TEA::encrypt(const byte *in, byte *out) {
" e4 V, J% d3 P, U0 G1 \31 encrypt((const ulong*)in, (ulong*)out); : K1 ]& z2 v" ^. E0 F1 {
32 }
: D. X7 S N: T* G6 Z33
6 b$ S% s3 \, O s- l2 i9 i34 void TEA::decrypt(const byte *in, byte *out) { 9 S" Z' e/ h7 e, y9 z
35 decrypt((const ulong*)in, (ulong*)out);
2 _5 ~8 q Q1 A/ d# ]- H4 A36 } # n3 |, \/ Y2 j& @8 m/ ]* A* ]
37
) D1 ?- ?5 n+ S+ }9 P38 void TEA::encrypt(const ulong *in, ulong *out) {
5 g) ^7 O5 @+ U: x+ U( H1 d39
" m5 J8 d3 z5 q' c40 ulong *k = (ulong*)_key; - t8 ~& _( o% G- D9 K9 Z
41 register ulong y = ntoh(in[0]);
1 S+ z% x- H+ M/ D6 F42 register ulong z = ntoh(in[1]);
/ q9 ~% Z4 b8 U( `" c9 V- \43 register ulong a = ntoh(k[0]);
" j2 k4 J. z7 T* a5 E44 register ulong b = ntoh(k[1]); : R5 Y# y) [; n9 f! y. I2 [8 x O
45 register ulong c = ntoh(k[2]); ' O$ U3 L# x1 J1 K3 E
46 register ulong d = ntoh(k[3]);
6 Q$ z, u/ Y% S' \& g0 r/ t47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 6 ?+ d; @+ v- y8 |. ^% j" @
48 register int round = _round; $ J0 z! k+ w9 u3 C' D
49 register ulong sum = 0;
* |; z, d9 K( \* y50 - K% N2 s' g8 o- G
51 while (round--) { /* basic cycle start */ " g6 Q- H9 c: B2 S1 W
52 sum += delta;
2 i3 H' ?9 M0 Y53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); & I* u9 _/ u: U* d" ]
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
! R5 E. _8 ?: m4 x8 f+ H3 \: L9 K4 a55 } /* end cycle */
& | m' w, L6 W0 X+ {' f56 out[0] = ntoh(y);
) f# E3 ?* x4 P: A3 U! R7 k57 out[1] = ntoh(z);
9 c6 p/ v; s" p- Y$ P3 x" s( L7 m58 } ' K2 b' ~/ e' e
59 5 ]1 b1 h6 P' |% f I
60 void TEA::decrypt(const ulong *in, ulong *out) { J, } ]. C# b6 }* l( P
61 1 S4 V+ {7 R5 O a& a8 H# n
62 ulong *k = (ulong*)_key; 1 r8 r5 Y% D# R2 u" P( W
63 register ulong y = ntoh(in[0]); ; j* M3 I* d, r* M, @
64 register ulong z = ntoh(in[1]);
; U" m- l, \6 X5 _+ i65 register ulong a = ntoh(k[0]);
8 b' o% j8 F' p0 q( m. C66 register ulong b = ntoh(k[1]);
6 L4 H6 o1 }; j2 R9 q1 ~# y8 |67 register ulong c = ntoh(k[2]);
' R2 E- \( l9 V+ {5 P* ]+ h& [9 v" ^68 register ulong d = ntoh(k[3]); . q3 q+ f+ p& S" L, U5 I# i7 }
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
$ |6 A+ s8 N \$ t! V. ^6 {70 register int round = _round; & N" [ X5 {4 Y; i
71 register ulong sum = 0; + O* r! ^0 B" m5 q5 g7 v5 P; P
72
+ }6 P7 e- X0 X4 U: j$ Q n, z g6 d8 e' Z73 if (round == 32) - _, E; M! j& p! r: E6 Y* G
74 sum = 0xC6EF3720; /* delta << 5*/
& i$ A( C8 M) ? |. z) M75 else if (round == 16)
i7 n. y# G6 c& s; q9 H76 sum = 0xE3779B90; /* delta << 4*/ ; q4 o% ~) n( c1 j' y
77 else 6 Z( |" }. s* T' ^& _( i) K
78 sum = delta << static_cast<int>(logbase(2, round)); * P$ O' x' B8 x: x
79 9 v- ~' x y0 [+ h- ~/ y
80 while (round--) { /* basic cycle start */
j4 E2 u9 Y& g* W81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
! @0 q; k9 N& \3 A- y8 N82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); ! A4 N& N! e2 B3 g6 \6 O0 g
83 sum -= delta; 2 q$ s. x& W1 M8 y5 Y) A
84 } /* end cycle */ 4 O; `7 e9 [" Y4 h/ T' }
85 out[0] = ntoh(y); ! R& W0 f; C3 A
86 out[1] = ntoh(z);
, X( Z/ K1 ^+ T0 x- f/ s! O8 H87 }$ E3 n7 t- y- s& f
& A! ~2 L. ^" c4 x6 Q" _需要说明的是TEA的构造函数:
% C- @! _0 Q+ H0 _TEA(const byte *key, int round = 32, bool isNetByte = false);
9 a% M: n7 A+ h$ n. G, F8 a$ Z# B/ h1.key - 加密或解密用的128-bit(16byte)密钥。
( G/ ~. P3 X$ I' d7 w; M. E8 ^2.round - 加密或解密的轮数,常用的有64,32,16。
0 c, M+ a: I f( x3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
i/ L4 M+ y6 H5 W3 h2 z
' \6 A) F r- \+ ~, h* f4 N最后当然少不了测试代码: |
|