|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
6 _1 Q% m/ P" e) G 2 #include <cstring> //for memcpy,memset
5 L2 O, r4 y/ W2 n 3
% J+ p0 C `# P 4 using namespace std;
7 M! j6 q/ {& r' w) G+ z 5 6 `9 M$ B- k# X) U% |* C! I3 n8 z
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) 0 r V; R7 z3 v
7 :_round(round) 8 {. z% N1 n" n- w: _. {4 Y
8 ,_isNetByte(isNetByte) { 0 y$ B& d6 n& g4 s7 y
9 if (key != 0) 2 c2 U5 i7 }0 |6 q A* ]- d' b* t
10 memcpy(_key, key, 16);
& p9 t2 |6 m$ a6 L5 }11 else
' ?! U& z3 M! m* R' _% c12 memset(_key, 0, 16);
8 {. Y: B' g0 X13 }
$ G) x& f4 c% y4 [8 u9 h* N. Y: _- k14
& f7 Y' _: R W9 G6 ~9 k15 TEA::TEA(const TEA &rhs) ( }2 v* D6 P1 ^2 B, e3 `
16 :_round(rhs._round) ! ]5 B/ L) e4 o( o" J, X5 X) D
17 ,_isNetByte(rhs._isNetByte) {
: x' e: Y8 L' ~. G! q6 b18 memcpy(_key, rhs._key, 16);
/ i% ~- p9 \5 ~* Y6 q' @/ h3 x19 }
" d1 u; |: e# E0 s20 + Z) b$ K, a, A% W; [# I0 h
21 TEA& TEA::operator=(const TEA &rhs) { 1 d/ [2 i/ }7 U- r: m
22 if (&rhs != this) { : c7 `0 _8 R3 i$ E: C& j
23 _round = rhs._round; 7 u2 F- u8 t2 M$ Q
24 _isNetByte = rhs._isNetByte;
8 R+ \- j/ j( N$ R25 memcpy(_key, rhs._key, 16);
` | A! V5 I0 D, l \, B' f) ^26 }
% p+ i9 ~2 d$ R( I$ P27 return *this; P, m, J; _+ ^7 a
28 }
' g' ], ~9 @! ^5 h7 `; k29 - V/ A8 U+ Y, R6 H
30 void TEA::encrypt(const byte *in, byte *out) {
! x" B# h8 ^& \ p& X31 encrypt((const ulong*)in, (ulong*)out); ! p0 z& h+ [ M3 b/ z; R- N% N$ v
32 } - @- g% n3 k" r' @. m* m8 N
33
/ A" U. i/ s2 p34 void TEA::decrypt(const byte *in, byte *out) { # r: ^& r1 F5 U$ w4 K
35 decrypt((const ulong*)in, (ulong*)out); 2 h# r8 U+ H" c$ V {+ l
36 } , L; Q) O3 ^8 V" s2 f* @1 P
37 / v7 I0 R n6 ^+ Y8 v8 L
38 void TEA::encrypt(const ulong *in, ulong *out) {
, O) I4 @; _0 l! p39
/ n- p! t t6 H( [% C: [9 c. r40 ulong *k = (ulong*)_key;
5 l8 E$ L, X$ A, W0 Q' x) A8 @' B41 register ulong y = ntoh(in[0]);
4 V S( A! ]" K& Q42 register ulong z = ntoh(in[1]);
$ v$ P) `* e9 W/ _; o43 register ulong a = ntoh(k[0]); ! e5 d E3 L6 [7 b+ X* W5 a
44 register ulong b = ntoh(k[1]);
7 Q4 W/ Z( W3 j& D; t( H' |45 register ulong c = ntoh(k[2]);
2 y# a5 x/ O3 B3 K46 register ulong d = ntoh(k[3]); ( g& c. |/ ?0 k3 J# [+ P( x, E
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
7 u j% V6 d0 _( B l- {9 f48 register int round = _round;
! I, F6 b& C& q49 register ulong sum = 0;
j y: m$ h3 x50 5 A0 ?# L: O' [) x1 v" ~% K7 G; M
51 while (round--) { /* basic cycle start */
6 L* m! |4 @6 f52 sum += delta;
1 v6 _7 b3 f; l- _. x6 Y53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); 0 e, e$ ?! s7 p" T
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); 7 }1 e7 v1 Q% j
55 } /* end cycle */ / Q. p3 v5 g# {' u& ^7 S: R
56 out[0] = ntoh(y);
$ q( w% Y. \! ?# r2 G57 out[1] = ntoh(z);
7 U# _+ V2 D I3 G+ \58 } % B5 H' U K/ R/ H& b
59
; T6 k" f( `8 ~: K* z60 void TEA::decrypt(const ulong *in, ulong *out) {
; {; L% t+ @9 R8 d( o3 P I* {61 % }/ v0 v0 N/ v* a2 `/ ^
62 ulong *k = (ulong*)_key; : u! ^6 a8 O1 Q5 P" z" u
63 register ulong y = ntoh(in[0]); : R" X7 g2 A7 X8 P
64 register ulong z = ntoh(in[1]); " H7 _. N& w# [, M ^& P9 Q
65 register ulong a = ntoh(k[0]); / O. T5 D$ A. I$ x
66 register ulong b = ntoh(k[1]); 2 F0 L$ C, I3 G) T5 T: G5 u
67 register ulong c = ntoh(k[2]);
5 X. D3 e6 c* v t68 register ulong d = ntoh(k[3]);
( j( D3 A) v$ G69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 4 z& |( x& S$ I& i
70 register int round = _round;
- l% \/ ~/ g K* a9 ^* V2 m71 register ulong sum = 0;
1 o7 L& O# V# B$ Z. a72 1 O. }: t* C) O, C
73 if (round == 32) ; K1 m! w, S" U& i( l$ C4 R
74 sum = 0xC6EF3720; /* delta << 5*/ - }; T: S) |7 p/ R* B
75 else if (round == 16)
6 Y; b5 S/ ~: E2 _4 e. ~) O76 sum = 0xE3779B90; /* delta << 4*/ ( F$ i) b, S$ F6 e6 F) h
77 else / H K/ P$ w6 k& H. A2 `# _2 n
78 sum = delta << static_cast<int>(logbase(2, round)); 8 }0 D& v1 l% U k: X' n7 |( q, \+ ~7 u
79
6 p5 H5 C `6 W80 while (round--) { /* basic cycle start */ # D& F, o; H; P5 ~+ ~
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); ) x7 f6 c$ l+ r2 n" y, e, k9 @
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); ' Y2 O9 |8 k5 h" X( d
83 sum -= delta; ' S! r# \# k' A. E" `; `8 s
84 } /* end cycle */
& q$ H" W& S" O z) c; P3 t; A85 out[0] = ntoh(y); & w9 r. ?8 S: s3 w6 _
86 out[1] = ntoh(z); 7 S( B) o2 h4 J T6 T" g; R7 u3 Y
87 }: @* W% J$ O) x$ `% c1 }" Z" W* }
0 R- w1 a7 b+ x( s
需要说明的是TEA的构造函数:
+ Y0 `0 J, d, H& S1 qTEA(const byte *key, int round = 32, bool isNetByte = false); 9 R$ r( {% ]4 a- K1 s
1.key - 加密或解密用的128-bit(16byte)密钥。 ' K. v# E0 E- T/ U0 p
2.round - 加密或解密的轮数,常用的有64,32,16。 5 \3 {3 R# b9 |0 S; b5 P
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
& S6 h6 W) b" `- ^5 o' D* g4 j
. `4 x+ v0 r {; N! K% y最后当然少不了测试代码: |
|