|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" # D: M4 k: w, |% A3 W; Z3 X
2 #include <cstring> //for memcpy,memset " R- I+ k" L* b; s# U* \. d
3
( ~. j: \* M& }$ i 4 using namespace std;
2 C5 u. e3 s. ]7 o0 e+ s 5 4 g- J6 Y7 x7 G6 c( S$ q& ^" ~
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
) h( ^8 d6 A. o- B( u7 x; O) S 7 :_round(round)
]- g5 L/ C4 p5 \8 c, ?, u 8 ,_isNetByte(isNetByte) { ( C, I3 U0 \6 l) I+ E& R
9 if (key != 0)
l; }% e7 g9 y( @4 O; m10 memcpy(_key, key, 16);
! b" }* j# |/ {, j) l11 else
. X3 m; g3 i0 S$ F; E8 y, c! e12 memset(_key, 0, 16);
5 q+ Y. j0 b, F# z4 p @! Z! c13 }
* x9 W: ]8 b. F! t s14 5 S+ s5 ~8 h; F, R" ?% h
15 TEA::TEA(const TEA &rhs) & o. s- |$ s3 t$ }; p8 h2 S5 h
16 :_round(rhs._round) 5 K. i7 S! f) o; Y
17 ,_isNetByte(rhs._isNetByte) {
3 t6 \2 ~6 ~ n% {18 memcpy(_key, rhs._key, 16);
: a7 }! q/ R- H8 l5 K19 }
* z& G2 Q- M- C* T3 `0 \# A8 x20
7 o! A: s% e1 s& Q5 ~ f0 H+ w21 TEA& TEA::operator=(const TEA &rhs) { 0 w" t7 D2 V2 W
22 if (&rhs != this) {
: y/ _5 Z& ^5 H' N# H( k23 _round = rhs._round; : \" q2 M+ Q; i- B
24 _isNetByte = rhs._isNetByte;
+ G/ S+ y& X0 R* l0 ]25 memcpy(_key, rhs._key, 16); ) d+ ?) s; M; @- F! L5 V' u
26 } * w$ w2 E0 [& p/ k' |0 H* ?" c! M
27 return *this;
$ j' g! o; z) q3 o C$ i28 } ' \- J! w( w& d/ |$ y5 N% B/ {" z1 A
29
5 \! F: N9 t1 r' ?8 F8 `* w30 void TEA::encrypt(const byte *in, byte *out) {
, q9 c. l! u2 s x- \% T31 encrypt((const ulong*)in, (ulong*)out); ' g3 `/ t% ^; Z8 J
32 }
( z5 t% a$ L7 f" g& ~33
% y3 N! O. j5 ^. H3 b- D34 void TEA::decrypt(const byte *in, byte *out) { ' I- Y) {5 J$ K3 C2 x# |( v
35 decrypt((const ulong*)in, (ulong*)out); 3 `, v& X$ Q: k, `# h n1 ^ c
36 } 8 p& H. |3 D& r) N H
37 4 S$ z; s0 o! ^# f- }8 {0 r7 L
38 void TEA::encrypt(const ulong *in, ulong *out) { " T# M$ \( I7 T, J3 W* H s
39
0 I* M/ t9 z4 ^* f o( ~40 ulong *k = (ulong*)_key;
/ A% _& f8 r" L1 Q41 register ulong y = ntoh(in[0]); 5 i. B( T- u& T* e7 `6 u x9 h" D
42 register ulong z = ntoh(in[1]); + c; F) O* L, e! l% l, Q% _
43 register ulong a = ntoh(k[0]);
' P- |; ]" y# v! A44 register ulong b = ntoh(k[1]); ' H8 `; J, l$ G" b# q
45 register ulong c = ntoh(k[2]); ' t( y8 ~' b( D# ^6 b7 k
46 register ulong d = ntoh(k[3]); 4 t# g# [$ v5 f) j2 {6 R
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 6 ~, A, C C$ U. j6 A! Y
48 register int round = _round; ! z) f8 ~! a9 b
49 register ulong sum = 0;
2 R* l; `) ^/ R9 X+ _$ C50 . b( {, W3 |( d1 p( J' W" d3 u1 l
51 while (round--) { /* basic cycle start */
% P) X& P0 O( W9 j4 U8 Z( V52 sum += delta; * m2 N! e( m8 n+ l2 i2 J5 c
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); 5 T0 w% A2 H0 X. n& W$ S. Q, h
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
" g m! T( j- v# y1 \55 } /* end cycle */
, j& O$ A+ t2 A1 y3 O56 out[0] = ntoh(y); 0 r# L5 d, X! C" j; G
57 out[1] = ntoh(z);
' l0 Q3 ~* f# Q58 } 0 q v* b7 i3 \8 L
59
; T' F! d" D- @2 |60 void TEA::decrypt(const ulong *in, ulong *out) {
( H; @! U" K2 j5 H# m& h1 p61
4 n! {7 b% t {* N62 ulong *k = (ulong*)_key;
) I- t7 {3 h% H2 n7 ]63 register ulong y = ntoh(in[0]); 3 }* c2 F- T' Y, \5 n
64 register ulong z = ntoh(in[1]);
. y; e* P. F2 ?6 Y65 register ulong a = ntoh(k[0]);
0 I% S8 N3 V [. s66 register ulong b = ntoh(k[1]); 8 w& {- A' E0 Y; V% p0 m4 E/ P
67 register ulong c = ntoh(k[2]);
/ U: |; l/ j( Q- [68 register ulong d = ntoh(k[3]); : y7 T' P8 ^3 \$ h* n$ r" ?5 W
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 1 u9 W6 k9 t& x% q$ Q; _
70 register int round = _round; $ f/ o) \7 i( L: F6 P; T% l
71 register ulong sum = 0;
5 ?) v. s4 N7 h72
: Q* P- [$ I1 H% a6 Q73 if (round == 32)
" M$ |* P1 \4 m0 _74 sum = 0xC6EF3720; /* delta << 5*/
( r1 ]" T0 ?7 Y4 M. B% c5 t75 else if (round == 16) ' K; J' F: ?* Q5 C" X
76 sum = 0xE3779B90; /* delta << 4*/ 6 H1 R8 x3 G" |* n. m9 `- i
77 else
1 S& R2 s4 V, O6 o78 sum = delta << static_cast<int>(logbase(2, round));
/ l% x) H, Y+ g0 t! @79
# X8 Q3 r. @5 k/ r80 while (round--) { /* basic cycle start */
. @% a) v6 k( `4 d4 D& M7 ~& U81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
# {, v9 M% n9 d$ J82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); * }4 R6 C. c4 Z9 K# y
83 sum -= delta;
" {0 Z( e7 U7 d+ c3 J" O) J( j84 } /* end cycle */ 2 ~( x& \6 b; O+ H# R' w
85 out[0] = ntoh(y);
3 U2 r8 r- K' F( A- w2 a86 out[1] = ntoh(z); & h" w. c6 ?5 G% o" o4 w5 U) F. X) Q+ ~
87 }: c: y* m! E4 V3 r4 E7 C2 v- n
' k6 Q* V. ~" i i% @, ?. ~) \需要说明的是TEA的构造函数:
Q% {4 b# u& l6 cTEA(const byte *key, int round = 32, bool isNetByte = false);
6 l5 d7 W4 @0 L" ]1.key - 加密或解密用的128-bit(16byte)密钥。 4 v9 s( S- A! P0 U ]4 I$ h4 o
2.round - 加密或解密的轮数,常用的有64,32,16。
7 q; I% E/ I1 W" L9 `3 O; Z4 J8 c) ?! S3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! + |6 P6 e9 R0 ~' H
- C, N! O4 q$ r# D最后当然少不了测试代码: |
|