|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" ' c: j& w3 O2 ? R: }
2 #include <cstring> //for memcpy,memset $ X0 n; s9 D6 L5 O
3 ) U( b [6 Q) j& X. K8 v; X8 E
4 using namespace std; 4 c5 J4 _: K9 d" [9 ~# Z% A j; s: s
5 1 ^2 Y6 h; P2 w, V
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
2 w6 R8 y( x7 M& [ 7 :_round(round)
* T) p- X' S7 R0 t4 u: u% U 8 ,_isNetByte(isNetByte) { # e+ U+ p, d9 b
9 if (key != 0) d' w2 b* E0 L+ F( o0 d: Z
10 memcpy(_key, key, 16);
" ?2 x% V9 C5 k2 U2 I" b5 e11 else
5 `+ E& s/ E1 h f3 f12 memset(_key, 0, 16); " X7 ~3 |& Q: s; u Y# d
13 } ; r4 e v/ n6 B
14 & U+ s; y# k: |9 d4 l3 \; d
15 TEA::TEA(const TEA &rhs) 0 `5 R- c# q+ S3 }& H
16 :_round(rhs._round)
) H! ~1 h+ z, b- x: Y! J17 ,_isNetByte(rhs._isNetByte) { N+ X3 N) N) R# q/ F3 K& u
18 memcpy(_key, rhs._key, 16); # {4 ]: p% W8 s( b x% W# [
19 }
! s5 U. ?3 x8 R, W20
6 M; H1 O1 G* U y21 TEA& TEA::operator=(const TEA &rhs) {
: M" e, E+ t, e2 Q* K) ]; X22 if (&rhs != this) {
# f/ H% M, y; i) C* I3 Z23 _round = rhs._round;
% ]; ~1 C0 Z/ w( x& [24 _isNetByte = rhs._isNetByte;
; b& w2 G$ ^ N5 |% v25 memcpy(_key, rhs._key, 16);
2 j0 u+ x9 f7 q' L$ U( B26 } 5 m" R/ F( Y: \
27 return *this;
- T" i, X6 ]/ P& r7 l5 K28 }
1 F4 a/ a; h; A: m, j* f29 : ]. n9 E. \+ Y7 S
30 void TEA::encrypt(const byte *in, byte *out) {
# D0 K" _/ x% K" m% Y" Z31 encrypt((const ulong*)in, (ulong*)out);
2 T% J; Z6 t% Z/ i. w; r32 } " `$ d8 [1 V% h5 [: |8 R9 x
33
e9 U7 Q; }; P: a34 void TEA::decrypt(const byte *in, byte *out) { ! Z8 H. h8 l; K- b, `4 O
35 decrypt((const ulong*)in, (ulong*)out);
- k, r) ?# K1 s' C: h4 r36 }
7 h& O/ g2 Y/ G4 W* e. }5 I37 " P' k6 b2 B5 M5 c" V9 K+ b
38 void TEA::encrypt(const ulong *in, ulong *out) {
. `0 a. q/ G+ A" c39
- h [% G3 _# \2 J/ D3 K40 ulong *k = (ulong*)_key;
/ @% o9 C* W" i) A+ a( v+ Q) p41 register ulong y = ntoh(in[0]);
9 k5 k. b ~; `0 d/ j+ g1 L) U42 register ulong z = ntoh(in[1]);
+ k* u, k( ^" ~& m& K0 y; {43 register ulong a = ntoh(k[0]); + j* I: N" H; i, w1 `8 c
44 register ulong b = ntoh(k[1]);
- F) ^% R# j& P- N, s% b9 V# r45 register ulong c = ntoh(k[2]); $ Y3 X3 v' u) R. B" q
46 register ulong d = ntoh(k[3]); % J/ R* X! Q3 u; O7 T7 h+ n
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ ; W0 X- i6 z1 A$ w
48 register int round = _round; # v/ ?$ y( P/ f# U
49 register ulong sum = 0; 8 p3 V. {/ H9 u, K2 X
50 % z M( C3 N: v! L' |
51 while (round--) { /* basic cycle start */ % H6 ~ m6 I; ]; C, U% n# [
52 sum += delta; P& r0 @7 w% m( U( [7 W
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
. J4 |+ j2 q3 l/ t P54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
) C+ e6 D( S4 T% K* n* }55 } /* end cycle */
% D& @8 p- y: ]3 V3 Z# c56 out[0] = ntoh(y);
/ I, r% I2 ]7 @% L) B57 out[1] = ntoh(z);
! S; K y4 _7 w \- ~- [ q4 }" l1 t58 }
7 g& U1 Q% i# n: ~) y59 ; t! k9 I+ H- W1 K8 @4 Z
60 void TEA::decrypt(const ulong *in, ulong *out) {
0 k$ N. R0 E$ ?. {4 e0 S0 j5 ]61 - P G( N" x( I; C/ I' G
62 ulong *k = (ulong*)_key; b& A k7 b- q0 {- M
63 register ulong y = ntoh(in[0]);
$ l! g- K1 k f( m64 register ulong z = ntoh(in[1]);
2 b) T) w7 l9 Z% P5 X9 r" e3 _65 register ulong a = ntoh(k[0]);
3 E9 D. M* F2 \2 i# _# x" H6 e' `9 ]66 register ulong b = ntoh(k[1]); - o5 Z2 K N! a- [9 G! }& T
67 register ulong c = ntoh(k[2]);
6 W: F$ n: J! C68 register ulong d = ntoh(k[3]); 1 n' O0 e% m3 T5 U4 l! @
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
+ G) J& E# g8 K$ s" X: C9 c/ F, x8 `70 register int round = _round;
" ?. Z! |% I" K+ l71 register ulong sum = 0;
F: C7 h' |/ t. S8 \7 R, l72 " |$ Z% [+ y7 Q4 k( s8 {
73 if (round == 32) 1 {4 K; E f& s# n& Q% l
74 sum = 0xC6EF3720; /* delta << 5*/ : t; e' h) B* g
75 else if (round == 16) ; w! { t+ i d$ x/ K
76 sum = 0xE3779B90; /* delta << 4*/
& H: Q4 v& m! i# b _: {77 else 2 ^, y* d) F5 p4 E
78 sum = delta << static_cast<int>(logbase(2, round)); , m3 y, U* F4 p% b* k& \8 W
79 7 b' |% B( D9 F# ?8 t, Z4 R
80 while (round--) { /* basic cycle start */
* _, r) T3 U% \5 e) x81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); 7 ~6 G1 o8 T" J" x) J
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
5 @% u# m6 U, Z6 i2 M83 sum -= delta; ! g" |8 A9 d/ q3 m
84 } /* end cycle */
1 Z l) B/ U5 M5 P3 _ `' f85 out[0] = ntoh(y);
: L+ I: F/ P y) V# c* V86 out[1] = ntoh(z); 5 f1 i0 r' u6 ` v8 A$ \. F. @- R" [
87 }: M E' V* w8 p
& M( Q% J* G( E3 U7 ?9 V1 J需要说明的是TEA的构造函数: & d3 I7 n/ `/ ]3 N: s6 v+ V& _
TEA(const byte *key, int round = 32, bool isNetByte = false);
4 w* E" W; R2 d( n1.key - 加密或解密用的128-bit(16byte)密钥。 5 E4 X! o1 B: S0 `
2.round - 加密或解密的轮数,常用的有64,32,16。 0 [, Z) w7 u9 n4 Z4 U
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! ! k2 S) R& x. l1 ^9 d3 O$ U9 s
+ a; k. H- y. o: D5 z最后当然少不了测试代码: |
|