|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" S2 h% F9 P( o% e0 ~# x
2 #include <cstring> //for memcpy,memset
& d2 p: W: P( u, r9 K 3
4 |# p9 j' A0 a7 i1 w7 J 4 using namespace std;
3 e X2 R: \ O 5 & |* s( e: P* L7 }
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) ! V8 o( l! P2 ?; e' p; k
7 :_round(round)
2 X0 g5 q; h" O) Y: r 8 ,_isNetByte(isNetByte) { 9 Y5 U. q$ X6 c& C
9 if (key != 0)
; H" b' h# P( |/ t0 z8 n7 {10 memcpy(_key, key, 16);
' P3 ?9 N: W0 w" H3 U7 p/ T+ a11 else ! s% C6 ^; X" h0 l. {- N7 F
12 memset(_key, 0, 16);
" Y3 n/ q+ f9 q2 ]4 t3 ?/ P13 } * R8 Q3 Q$ f9 I2 I; b
14
. z) `, f3 I& i3 f6 C15 TEA::TEA(const TEA &rhs) * l) ~, S6 A5 M! a
16 :_round(rhs._round) & z/ c8 }0 v- E0 D/ c3 P! z
17 ,_isNetByte(rhs._isNetByte) { 4 g3 S& v- f: p8 a1 V
18 memcpy(_key, rhs._key, 16);
3 v' Q! E( J p/ m19 }
1 U: M- w8 O4 S9 t20 8 |6 P* t( U( l! @
21 TEA& TEA::operator=(const TEA &rhs) { , {% u! N! h1 B- t2 M Z `6 G- {
22 if (&rhs != this) {
+ E( N# U$ U! y4 `& s8 e7 p23 _round = rhs._round;
3 r* G; E: L3 R7 l$ q, r& ~! i% i: o24 _isNetByte = rhs._isNetByte; : d4 N1 U( j2 u) B8 |5 d* l
25 memcpy(_key, rhs._key, 16);
. Y+ c, c. T$ F4 }- e1 }% p2 |. ?26 } 5 q' d3 a0 Y. g$ |& O) F
27 return *this; : L5 D# F7 S9 s
28 }
; L( }0 s% |0 ~( i! L% [ D29
; y/ L5 i8 c L30 void TEA::encrypt(const byte *in, byte *out) { 8 c" X% i {" w, y7 f
31 encrypt((const ulong*)in, (ulong*)out);
1 G& C" D$ L: ]32 } / D; B# \" p8 J" W5 |, K7 J& D
33
. F$ o. f$ b" }- q( l6 Q34 void TEA::decrypt(const byte *in, byte *out) {
( f+ d7 }# G8 o' P35 decrypt((const ulong*)in, (ulong*)out);
2 Y, l# S. G5 T* R1 L* c36 } 0 c: t9 R; P% V2 y+ L" e) t6 G
37
% }' K- s: i+ H# t% d38 void TEA::encrypt(const ulong *in, ulong *out) { ) F9 T& o: i8 |& x; x* c Y
39 , j4 d, R3 @7 v+ O( L
40 ulong *k = (ulong*)_key; ' C9 r2 A# V3 O1 C/ g" ]
41 register ulong y = ntoh(in[0]);
: t1 v, t* F+ L; S0 H0 \- d! r42 register ulong z = ntoh(in[1]);
8 D- |# _: O0 t) r0 D# ?3 `- g( O43 register ulong a = ntoh(k[0]); ) b4 e* S4 d6 T2 y2 s6 Q' Y6 d
44 register ulong b = ntoh(k[1]);
8 i! r' d! m, H) S9 m- N/ P45 register ulong c = ntoh(k[2]); ( L2 m) R$ _; S$ O7 x
46 register ulong d = ntoh(k[3]); 6 q8 |* f3 S G* C+ ? w2 D% @ z s
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
: }: T V w1 P5 a3 X9 P! e48 register int round = _round; # p, ~/ V) `% Y; c. c! F: `, t4 B
49 register ulong sum = 0;
- K( W8 \: R& z& V$ P- _* u9 O50
9 d/ s$ q# n- F: b" |( p: T51 while (round--) { /* basic cycle start */
- [: T5 @% ^7 u2 I+ |2 ?52 sum += delta;
1 ~5 o8 G w$ ~- Y53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
- w2 ^. \' j+ F5 r: k54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); : l' F; O0 f' p6 ~
55 } /* end cycle */ 4 i0 b. r3 e$ i# A8 t
56 out[0] = ntoh(y); / E- y5 c' @ E% S$ `8 e! K
57 out[1] = ntoh(z);
: N# @4 j) o* t5 a+ g( b; a0 K' _58 }
# b r/ R+ i! j59 # J* d3 @' e9 h8 W s
60 void TEA::decrypt(const ulong *in, ulong *out) { 3 T- g4 X. X+ V6 G$ d
61
8 @, @5 F7 h) P- @/ ]4 c, X9 g62 ulong *k = (ulong*)_key;
" ^+ j1 O& l7 A& _63 register ulong y = ntoh(in[0]);
" z c! r2 V! Q+ v# i2 _64 register ulong z = ntoh(in[1]); 0 N+ h# U% c- U6 c
65 register ulong a = ntoh(k[0]);
+ Y0 E, ~8 M# D8 M, @66 register ulong b = ntoh(k[1]); / O* ^; ~' ^ P8 g. M+ A( o
67 register ulong c = ntoh(k[2]);
2 x3 n& G5 t) X* y& M4 t+ [68 register ulong d = ntoh(k[3]);
0 a) f: U+ C5 K# s# G0 X2 |% S9 j69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ o) `- ]. q* L' j/ V- }) |
70 register int round = _round; + H+ [8 \9 W5 {
71 register ulong sum = 0; % B6 x# T+ C' y- x$ T z& ^
72 3 Q! l. Y# P5 D! k, v2 i5 \9 [1 y ?& t: f
73 if (round == 32) D) [. i# b& m- ]* U* `5 N
74 sum = 0xC6EF3720; /* delta << 5*/ 5 t8 A8 k9 B% W% z" p; W
75 else if (round == 16)
- V0 `, M' Q# E s, o N76 sum = 0xE3779B90; /* delta << 4*/
; G( |' s! C2 k2 }( W77 else
" a. k5 v( R6 X: O78 sum = delta << static_cast<int>(logbase(2, round)); o7 ^3 [$ }9 F& U
79 ) M; _$ F1 j+ Y9 N% p) p! g; o
80 while (round--) { /* basic cycle start */
: r% s* l! ~, f( }: ~( Q7 d. H81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
& u7 X( F! O! @& |: c: U: W5 V$ J82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); 3 H' }' L$ ^& X6 o; A6 G, x( s
83 sum -= delta;
& u* a! q$ s3 W& G' F' X0 T& o84 } /* end cycle */
5 L8 A0 _, O2 l& o0 n' x0 b85 out[0] = ntoh(y); 8 p, h/ N* C/ n7 u/ o- `
86 out[1] = ntoh(z); 5 l6 M8 H5 P. C2 }2 _4 Y9 H
87 }
# |% i& o1 D2 q2 z5 z s4 {
" s- K+ ~/ K6 u7 w6 O需要说明的是TEA的构造函数: " j5 g2 [: `: x, \$ z# \4 `
TEA(const byte *key, int round = 32, bool isNetByte = false); 3 M+ b6 B8 ?/ M" t/ T2 j
1.key - 加密或解密用的128-bit(16byte)密钥。
% t3 z# c' X* i+ F2.round - 加密或解密的轮数,常用的有64,32,16。
1 T+ ]% j2 E& X3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! 0 T( J) Q9 `4 F7 S) ] j1 r
. ^: d2 H2 q: a3 `; D9 E8 I最后当然少不了测试代码: |
|