|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" 9 [: o8 x& K3 f: ~2 ]
2 #include <cstring> //for memcpy,memset
/ e7 |: r6 j% h" M) W 3 " H# y6 w& G+ ]
4 using namespace std;
2 \% Q& W( N" r 5 # c& s6 A W/ p5 Z$ @
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) ' u, o" p" X- u k$ q/ A4 j9 H, d
7 :_round(round)
2 J( b3 W; \- v! {5 v: ~2 c7 X 8 ,_isNetByte(isNetByte) { 6 m: H" p! @0 }$ z/ F% {( f
9 if (key != 0)
% ~9 C( V: [! J, y* Y* |10 memcpy(_key, key, 16); - h! Z/ I* Q& _1 S8 r, c1 }" H
11 else
0 z) [2 L$ M: L4 B" q5 A12 memset(_key, 0, 16); - `9 V4 m4 K2 u" Q0 [, x }1 o
13 }
- @0 V2 l4 Z2 K14
, D2 i! u( u1 x/ D6 U1 J4 _+ E15 TEA::TEA(const TEA &rhs)
- Z1 P* P+ g; r9 A) Q7 J# o16 :_round(rhs._round)
/ Q& c) s% E' F9 t17 ,_isNetByte(rhs._isNetByte) { 9 m8 T+ n3 T6 i3 N- z
18 memcpy(_key, rhs._key, 16); % w7 `+ y* R# ]2 l2 Y/ z
19 } : }; E& c* ^4 l; E
20
e7 P: ]$ X1 N# c21 TEA& TEA::operator=(const TEA &rhs) { - d1 \% K9 H, C, _
22 if (&rhs != this) { . ?; B) W; g. I3 {3 I1 s
23 _round = rhs._round;
' R/ x8 D$ Y" ~+ ^& }24 _isNetByte = rhs._isNetByte;
# Q$ Z+ Y' j$ x! l l6 x25 memcpy(_key, rhs._key, 16); $ Q3 y+ S4 p; `" V
26 }
3 ?5 ]2 j1 t: k1 g2 v, Q' Q27 return *this; . Y7 o- F- P6 ^( D' z; c
28 }
$ U* ]5 e, F# s- }6 z6 y29
$ ^8 n7 G0 l7 l1 X) X+ \30 void TEA::encrypt(const byte *in, byte *out) { ) Q; e) W) }1 k5 ^$ y) D! c+ `) q$ g
31 encrypt((const ulong*)in, (ulong*)out); % G! K% U( F6 @1 n
32 } % E% m( s' ~7 _+ S% [" }/ }
33 ; L9 N$ u9 z! c0 S
34 void TEA::decrypt(const byte *in, byte *out) { : m, X/ p, z2 Z4 d
35 decrypt((const ulong*)in, (ulong*)out);
* Z" r. w( w. ~* [/ a' n36 } 4 k, |- ~+ a9 c% V
37
' L) `: |% F5 F; o9 \) E5 o38 void TEA::encrypt(const ulong *in, ulong *out) { ) F4 K% `, d+ N+ D* M0 Z9 X, t
39 0 y0 _" {; B: X7 R O
40 ulong *k = (ulong*)_key; ( D [ |+ j3 |2 A0 V* ?2 l
41 register ulong y = ntoh(in[0]); . \2 z' s+ R5 i' t3 J
42 register ulong z = ntoh(in[1]);
) H* r" K( e7 E* k43 register ulong a = ntoh(k[0]);
2 @- \ f. ^4 Q9 ?! z5 W4 W44 register ulong b = ntoh(k[1]); * I7 x; w8 ]* j' u4 `& N# Q, E! m
45 register ulong c = ntoh(k[2]);
% B* U# D( O6 R) S2 k/ s9 c46 register ulong d = ntoh(k[3]); ; s( Q5 A* Y$ |* v3 ]3 A+ D5 i
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
5 X' n8 q/ w6 W% Q48 register int round = _round;
; _3 A4 U! n% L) Q( q" ~49 register ulong sum = 0;
! M! d" |3 R6 ^' _& S+ J# d50 {& T/ u1 s2 s% [% F
51 while (round--) { /* basic cycle start */ 7 G% X' J* H& e- M# r, R
52 sum += delta; & x! z' S9 A9 P( ]' p
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); c1 P( q% C8 m7 n- j
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
5 t: E. C3 O/ d: r55 } /* end cycle */
3 B/ t+ } k! r56 out[0] = ntoh(y); . s8 o8 {7 Q, N2 [( Z
57 out[1] = ntoh(z);
! Q. `7 Q$ Y& W$ J1 u58 }
/ F+ j, m" A R: }+ ^$ H59
8 h2 T% U4 E' @3 t9 w' L- H5 Q60 void TEA::decrypt(const ulong *in, ulong *out) { ' x/ {6 C5 e" J! U" Z
61 " J- V6 w) Z* H% |, \2 O
62 ulong *k = (ulong*)_key;
; _9 o8 z2 S$ f63 register ulong y = ntoh(in[0]); % g; p! A% ^; o( X! c" J8 Y5 t
64 register ulong z = ntoh(in[1]);
Q# x# i b$ D' k65 register ulong a = ntoh(k[0]); % A6 [1 R, ^, S- w. p% G
66 register ulong b = ntoh(k[1]);
( s* ~( \+ v. H W c67 register ulong c = ntoh(k[2]);
3 v! U/ i. g3 u" L- t68 register ulong d = ntoh(k[3]);
7 P/ g! K$ J" J( c2 P69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 2 }3 d U. a0 A( t+ Q" v' `
70 register int round = _round; ! }9 P4 \" g& `9 k# W( e
71 register ulong sum = 0;
6 q- Q2 u) I6 S9 Q72
$ A; H$ L* m3 I% ]4 `& F- A73 if (round == 32)
. W: i7 Q# c& L% M, R74 sum = 0xC6EF3720; /* delta << 5*/ ' s* p$ A/ \* y: A
75 else if (round == 16) 8 V" h2 y$ P' d; C) z; Z
76 sum = 0xE3779B90; /* delta << 4*/
4 ]+ }1 s; z K2 f( R Z77 else
4 j5 W4 R+ F+ \78 sum = delta << static_cast<int>(logbase(2, round)); * ?, g" [3 I; i1 U
79
0 d& T+ u7 G3 u0 Z6 r80 while (round--) { /* basic cycle start */
" f+ R/ w; K$ y2 q% t3 I81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
/ } h$ \% z/ z( @4 F5 w h: o% |5 P82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); / C9 K9 E5 w9 n, ^
83 sum -= delta; " d6 d- ^. D1 o" }/ t% R6 F* I
84 } /* end cycle */ 6 Z# C% C' r4 W* a
85 out[0] = ntoh(y);
# u4 d- @& r; _# Q* t% x) S/ P86 out[1] = ntoh(z);
* r; w& C3 p6 w: A7 p1 r8 Y87 }
% w" z( f) x, H0 S
% g4 C( W' m9 ~2 o, l; `需要说明的是TEA的构造函数: 2 z6 y6 A) ~9 _" [5 r& ?
TEA(const byte *key, int round = 32, bool isNetByte = false); 9 ?; R6 H/ H1 y% Q& L/ `- Q
1.key - 加密或解密用的128-bit(16byte)密钥。
+ ]9 \1 e" Z! ?+ G- P- E4 a2.round - 加密或解密的轮数,常用的有64,32,16。
0 t7 u9 S1 ?! O9 r n; M1 B3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
+ k. q, `# A" H) O6 q7 d, d3 x) S/ a1 `4 X" f' {' ?
最后当然少不了测试代码: |
|