|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
9 q" P8 Q( x2 F. E" m. T F 2 #include <cstring> //for memcpy,memset 4 N+ a8 H3 r0 B; ]
3
9 }' E9 A3 W | 4 using namespace std;
8 q% l% R; x% C) r/ }+ z8 j 5
; l* z. V. |, |( l4 I- B9 f 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) / \+ U8 A# ? E
7 :_round(round)
8 x! g- p0 r! b3 |0 a 8 ,_isNetByte(isNetByte) {
9 n- m* H/ Q5 @& c 9 if (key != 0)
7 z3 ~* r3 D8 t10 memcpy(_key, key, 16);
# v: h! v5 T/ o. C3 M11 else " N8 e8 g) N/ u" Y4 C
12 memset(_key, 0, 16); * S& J3 O# f% P6 s# F
13 }
5 f) ~- h7 `; R. u( c3 D14 , Y$ C. l o: T! b( Z4 }5 C
15 TEA::TEA(const TEA &rhs) 7 G- R" l. F! K
16 :_round(rhs._round) 0 I- C& V+ }$ m& m( y7 J
17 ,_isNetByte(rhs._isNetByte) {
0 U& W9 q! t* ]18 memcpy(_key, rhs._key, 16);
8 e" P( c% k" H19 }
0 V7 C* H& P9 _: G4 B a. I7 m20
# ]: J/ g1 d4 s k21 TEA& TEA::operator=(const TEA &rhs) {
2 a% ?3 ^9 _7 U( V22 if (&rhs != this) {
" L* l0 _. A0 H7 J& m; h8 q1 e$ d23 _round = rhs._round;
6 O' N( f% ]; Y, o* a" y$ S24 _isNetByte = rhs._isNetByte;
) y7 P% S; Q* F, |' ~& b u25 memcpy(_key, rhs._key, 16); 9 q0 S) R7 x' t
26 }
5 `+ l! M6 V1 @/ e27 return *this;
! H$ _3 f7 `1 P$ p2 E4 x" n. y28 } 4 x4 a1 D! g. R5 e6 N. ?8 j: ^2 e9 P( Y
29 % J& Q1 b/ I5 K
30 void TEA::encrypt(const byte *in, byte *out) { % q* R) V& e- `5 Z P0 z
31 encrypt((const ulong*)in, (ulong*)out);
4 W) y# w6 u% }, y: t3 a32 } 4 F+ o/ F( }9 Z& e- T& [1 Z
33
! L- i4 y5 M) G' Q& `4 F+ o34 void TEA::decrypt(const byte *in, byte *out) { 6 ~6 A/ U# `- P' v2 E% T& g# h
35 decrypt((const ulong*)in, (ulong*)out);
5 L1 d: m& _7 K4 m! o36 } 7 W+ `! g8 R* S1 l0 s# g
37
3 t5 H) r' j" B" G$ l38 void TEA::encrypt(const ulong *in, ulong *out) { 9 L4 }9 A+ v+ I- ^2 l+ ~
39
# |$ M1 [# m/ k& k* s5 Y40 ulong *k = (ulong*)_key; 7 X" f2 A, x z
41 register ulong y = ntoh(in[0]);
- c Y4 ?. ?. u2 i0 v; N42 register ulong z = ntoh(in[1]);
. b4 j& F5 p# e \0 m8 d43 register ulong a = ntoh(k[0]);
2 }" U9 ^4 ^; ]8 m! a2 B6 e44 register ulong b = ntoh(k[1]);
: P; K" C/ [( u' S; ]9 I% g45 register ulong c = ntoh(k[2]);
3 k t) \7 _/ h2 @2 O: B46 register ulong d = ntoh(k[3]); 6 m, ?9 q( s' E2 w
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ ' {( f( T' }. g5 v6 \* k" G
48 register int round = _round; : e$ o0 B7 q" i# V5 [* y
49 register ulong sum = 0;
) \/ n1 Y0 h' u6 _7 w1 u( ^* q4 H( k50 2 |, t" }) b1 ^" W/ z r6 _ z- e
51 while (round--) { /* basic cycle start */
( j2 _0 a# Y7 }, `$ q; p52 sum += delta; : J* p' J0 j4 ` x7 P
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
! R4 N1 J c7 G0 T: s) K7 B54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); ) c; N) y. m5 V* I6 v: l, t
55 } /* end cycle */
! M9 t) q0 ~+ ?. u/ d56 out[0] = ntoh(y); 4 l4 J; z) [7 T r4 W3 r9 t/ e
57 out[1] = ntoh(z);
+ c; M3 Q- V3 h+ [- A& t58 }
8 _0 o) m- ~+ Y d59
A6 Y+ g' f( _9 z4 z5 f60 void TEA::decrypt(const ulong *in, ulong *out) { 8 ^+ W; W& ]0 a( O$ M1 d4 q
61
0 y4 z: O2 V2 e2 J+ e9 x! ]$ f, W. ^7 A62 ulong *k = (ulong*)_key; ) ^% G+ o" `3 E
63 register ulong y = ntoh(in[0]);
' ]4 z# {" {% c! | j64 register ulong z = ntoh(in[1]); / _+ q/ A, w p. |9 w2 t8 \
65 register ulong a = ntoh(k[0]); ) F/ Y3 ]( x/ q! n4 d8 _
66 register ulong b = ntoh(k[1]);
( w9 d, O6 l! N6 S3 ]" @% B67 register ulong c = ntoh(k[2]); 0 Y/ W# Q- R8 U1 g! W- x" \2 A) v/ o
68 register ulong d = ntoh(k[3]);
1 {/ S1 T6 N. }5 O' P' b* D* [69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
8 z3 e7 Q0 c+ m70 register int round = _round; 0 ?& j. H# l4 s7 J5 \* Y* C7 C" Z
71 register ulong sum = 0;
: \# F3 c# Q# x3 ~5 [9 ]72
. R3 ]6 H |) U" p73 if (round == 32) : p4 J; g& I! M
74 sum = 0xC6EF3720; /* delta << 5*/
* h- J8 K) O5 c" ~" d- P" z& e# k75 else if (round == 16)
0 d: e9 D* H; Z( x6 N. z76 sum = 0xE3779B90; /* delta << 4*/
# H' s7 i: C) |7 _" I77 else
! f, Q# [1 ?9 f$ ]78 sum = delta << static_cast<int>(logbase(2, round)); 5 [, p$ \ D% {: I' L/ R
79
9 B8 f: u8 w8 w9 U) [9 \. L& G0 {80 while (round--) { /* basic cycle start */ . o' Q6 b: M/ k; n+ U( X# ^% V
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
4 r( _8 i3 g3 P' T! C82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
3 b; [. t( i( V* J1 \( J6 {% `7 m' N83 sum -= delta; ' n$ ~% n1 s; t4 T$ K4 D9 H
84 } /* end cycle */
H& o+ M1 F5 e, r% {' s85 out[0] = ntoh(y);
- ]2 _& j7 Y9 v86 out[1] = ntoh(z);
3 O/ @5 B+ V( P- ?) V/ S4 I87 }
! a" X$ W/ |) m2 O' H) X8 l* q2 \- K% g0 _
需要说明的是TEA的构造函数: + w w8 g2 z' Y
TEA(const byte *key, int round = 32, bool isNetByte = false); " j2 a3 h" o, w+ Z, b
1.key - 加密或解密用的128-bit(16byte)密钥。
% N/ U1 Z$ O; H/ y5 O% G/ z$ h i2.round - 加密或解密的轮数,常用的有64,32,16。 2 Z, T1 C) T$ k1 F' z8 [( h7 _% s( u
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
4 Z5 S# D& W7 X7 `7 |+ p3 V+ K( a$ y/ T* }( g! r
最后当然少不了测试代码: |
|