|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
% `6 _: A& i0 n8 l$ @5 w 2 #include <cstring> //for memcpy,memset 5 s( a6 R' z" f
3 2 b" S$ q( S4 u: `# D+ B
4 using namespace std; 0 R5 A: q) s: u2 f
5 % b" M3 L$ T* R, t7 k2 G
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) ( h$ s8 c. g7 W2 `0 B
7 :_round(round)
# X, G* ~: U# w+ b9 L& H 8 ,_isNetByte(isNetByte) {
5 x* ], ~( o- J/ D. G2 g4 C/ c 9 if (key != 0)
9 ? o5 D7 c! I10 memcpy(_key, key, 16); ; b8 f5 D, u$ X. d
11 else 4 O4 A' }4 S9 J/ B
12 memset(_key, 0, 16);
- i8 \. }7 V. q8 F* |$ k" K13 } $ }1 ?& ?) `3 C# B( o7 g. U
14 5 a) W! H. @% C0 @, q
15 TEA::TEA(const TEA &rhs)
# [6 r% C* _; A) R+ P16 :_round(rhs._round)
1 V/ [3 p* U4 I1 C- x2 _17 ,_isNetByte(rhs._isNetByte) { 8 _2 D: K& i5 x% [
18 memcpy(_key, rhs._key, 16); + \: A* q" i" m" c( }
19 } ; M* U! [* Q, ^: H
20
% ~( n1 J* V% L2 z8 s8 n( k( I21 TEA& TEA::operator=(const TEA &rhs) {
9 Y$ `* o$ W% F) y. A22 if (&rhs != this) { ; q ~. a" E' |) r! a# K6 N5 D
23 _round = rhs._round;
3 |# q' S$ S- Z24 _isNetByte = rhs._isNetByte;
) X7 Y" s7 l! M: Q. j5 s+ [25 memcpy(_key, rhs._key, 16); * \5 C# \9 l0 x0 k. z, h) e
26 } ( M3 ]$ d O9 M9 d
27 return *this;
+ D# P {2 P9 i! j8 U' g2 `' H28 }
0 i5 H1 U0 E- t" T A" |29 ; W) {6 O( o3 L5 p# B& G
30 void TEA::encrypt(const byte *in, byte *out) {
1 L; q2 q4 ^, |4 E! }3 l- D31 encrypt((const ulong*)in, (ulong*)out); ; I7 t6 ^; @0 n, Q! D
32 }
7 G: Y, A2 g& ~33
$ \5 P9 O- R1 u0 X34 void TEA::decrypt(const byte *in, byte *out) {
( [% d4 r" _1 h35 decrypt((const ulong*)in, (ulong*)out);
% v: v/ v$ i5 x) r7 r8 v8 ]36 } , e; e- v& C: D/ W& g" @6 e% @
37
( q) I1 l) ]$ y' ^# p38 void TEA::encrypt(const ulong *in, ulong *out) { & }9 N( r6 T2 K3 ~# [2 J# K6 }
39
) B& a) q0 l3 i; A40 ulong *k = (ulong*)_key; 5 m; j7 y7 H& _
41 register ulong y = ntoh(in[0]); ) ]6 M+ \4 ^- o5 N" u& t: R) w/ R
42 register ulong z = ntoh(in[1]);
+ n6 A3 w2 o% C9 o; p2 w; T/ N43 register ulong a = ntoh(k[0]); + @7 R/ w8 Y2 k9 z1 l
44 register ulong b = ntoh(k[1]); 0 I" q+ _; z) ^) \5 C/ h6 L
45 register ulong c = ntoh(k[2]); 9 l- e3 n! _6 b6 Y' [( @$ }
46 register ulong d = ntoh(k[3]);
" e$ f2 Y- E) L47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 7 [: D8 H( P+ ?* b) e) R+ \
48 register int round = _round; . _& J$ u |; k9 b* B7 c
49 register ulong sum = 0;
+ A) o A/ Q- r50
( ^$ M' E& J( X1 j( E6 I51 while (round--) { /* basic cycle start */
: D9 r5 T l) ?2 w8 R( A* N52 sum += delta; " ~) E' W3 |$ }5 a
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
4 q7 x4 s0 W1 L8 T. {54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
U+ w& W8 Z. u! x+ ]. Q7 y% F' p55 } /* end cycle */
% R* ]$ H* r. s1 C56 out[0] = ntoh(y); 1 p& v, p `( O; C* C
57 out[1] = ntoh(z);
- K& K" I2 E$ z, }& M58 }
1 w8 x, g( Q3 D59
4 w5 g& [ T( }7 ~/ z5 N60 void TEA::decrypt(const ulong *in, ulong *out) {
0 j* d0 y' @% [$ E: M$ C. t61 1 x. U: T" w2 r' |
62 ulong *k = (ulong*)_key; - V% D: W2 f; R' v- G5 v8 c& u
63 register ulong y = ntoh(in[0]); " }! K5 R7 w/ m
64 register ulong z = ntoh(in[1]); 7 j0 n* T: Y# x P6 q: d% P' `
65 register ulong a = ntoh(k[0]);
X V: D1 L8 g) Q66 register ulong b = ntoh(k[1]); * N& E$ Y- N# I$ e2 r9 i, G/ l
67 register ulong c = ntoh(k[2]); ! c3 L8 A% r0 ^9 ~
68 register ulong d = ntoh(k[3]);
& n8 _' m/ @' a H) \7 [( V69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ . Y$ E2 [) ?6 e5 B u- B
70 register int round = _round;
3 a7 W; `$ l5 X4 K+ e71 register ulong sum = 0; 8 k* k4 K: `6 R( Y3 c
72 ( ^1 ^6 o) R* ]3 J% `% W' h1 ^
73 if (round == 32) , ]1 M: ^, W4 Y4 p; P
74 sum = 0xC6EF3720; /* delta << 5*/
4 P5 p" X5 o8 Q$ K75 else if (round == 16) . K/ K0 b/ V/ @* d: N% W. k
76 sum = 0xE3779B90; /* delta << 4*/ # X) ]( ~4 c/ S% ^/ R; d
77 else
! u4 N3 u$ Z1 a- X78 sum = delta << static_cast<int>(logbase(2, round));
# c; s: u+ B* o6 z6 T79
9 @4 t4 _/ ]1 I( f, u# G$ w& _9 d80 while (round--) { /* basic cycle start */ / x, _- j' i* u# ^1 y
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); " a: y5 ~; I9 i. L
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); . S. K6 E" p# R! N! h" n
83 sum -= delta;
8 M$ W6 S8 Z7 d7 V: J84 } /* end cycle */ : Y9 H- }4 ^. ?, Q* L) G& F: a% i6 j
85 out[0] = ntoh(y);
: F8 h3 a! _( F: m6 ]86 out[1] = ntoh(z);
/ x& q/ Q6 {) |8 T/ N+ v/ H& U( Z J3 f4 z87 }
' O1 O8 y4 }. n; I3 h% G# S7 F
# i! L* M7 x7 t& B需要说明的是TEA的构造函数: 3 Z, }6 g# P! O+ @* ]0 Y& ^ c, Y
TEA(const byte *key, int round = 32, bool isNetByte = false);
( G7 a; @ X8 `* P5 J1.key - 加密或解密用的128-bit(16byte)密钥。 ! v7 [ L5 h5 b: q. r: p) f
2.round - 加密或解密的轮数,常用的有64,32,16。
0 T- F; _+ ~1 |7 _3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! ; @/ ?' P' m' H% C. Y; c/ }. @
r8 t( C/ G* c2 \) \最后当然少不了测试代码: |
|