|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" ) d% z' h# ~4 G4 t& w& e& U8 N
2 #include <cstring> //for memcpy,memset 9 A! D! C( v) E/ P1 ^* o v* J9 N4 w
3
- ^8 p& F. ?/ _( Y 4 using namespace std;
4 L$ v4 C4 w- Q7 \/ R# j: M 5 % A+ B9 _2 L- u) z
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
& e1 h& u* m) l k 7 :_round(round) , h4 M! S4 E, r" R* [0 L4 T1 V; N
8 ,_isNetByte(isNetByte) {
6 d9 i; A; `9 A/ V3 j! Z 9 if (key != 0)
* D! m3 O& U1 r( c0 K10 memcpy(_key, key, 16); 9 p+ [1 @- }! g$ n- H* R8 ^
11 else
6 P [4 x {! j. x( c12 memset(_key, 0, 16); " B4 ]# Z, {) _5 @' q+ k0 L1 p4 p M' Q: P
13 } 7 J! ]& D% a4 ~ i6 ^) j, }
14
$ S3 d l- f+ g. ]15 TEA::TEA(const TEA &rhs) 1 H/ C# T2 x5 r- m* ?
16 :_round(rhs._round)
+ v- }$ o v* f( M& t; T17 ,_isNetByte(rhs._isNetByte) { : @# C3 D, M/ U6 h
18 memcpy(_key, rhs._key, 16);
; t! q7 g; N; t$ q19 } ( T/ Y2 o( `& Z+ x6 } B
20
! k6 ~9 t9 ~1 a4 S5 |21 TEA& TEA::operator=(const TEA &rhs) { % X- ?% W, n& {8 J v; j6 Z
22 if (&rhs != this) {
* `; Y2 f4 M* P# B f! A23 _round = rhs._round;
& v! G; D7 K2 J24 _isNetByte = rhs._isNetByte; . t) g- W* R( ^- `
25 memcpy(_key, rhs._key, 16); + B+ g- b8 Z Y- v" ~5 C
26 }
) ?3 K; [- @& B, B7 x27 return *this;
$ ^% G$ }- t k2 m" R- r. S28 } $ |9 w" h2 H- O' D/ I, R) h
29
$ G% C8 U2 F; F0 J( d30 void TEA::encrypt(const byte *in, byte *out) { / J, W4 D- z! E
31 encrypt((const ulong*)in, (ulong*)out); 0 x- r! R7 s) _* o9 c% f
32 }
7 s- a4 w+ j$ @, u* q$ U$ F33 5 p- R" S# [1 M2 h: N$ L
34 void TEA::decrypt(const byte *in, byte *out) {
. f* X# B& n: i' t: A* H) Y6 _35 decrypt((const ulong*)in, (ulong*)out); - Z3 V9 x& G$ b; Z' h6 Y- i- `/ r& W
36 }
0 x- y: K: {- E j; z) h3 ~* B1 p37
4 t- y* X! T! j0 }5 ^; {% n% w$ |38 void TEA::encrypt(const ulong *in, ulong *out) {
w3 [3 g. S3 ]: E39
! ~/ Y2 b$ z- W5 ]* Y' G3 K40 ulong *k = (ulong*)_key; & [% I1 v+ s1 T; ` T9 ]7 p
41 register ulong y = ntoh(in[0]); $ g- z$ X2 o7 X L6 b, `
42 register ulong z = ntoh(in[1]);
5 n8 ~! Q2 ^: o) k& m8 ]43 register ulong a = ntoh(k[0]);
6 p$ ?4 D4 f& x44 register ulong b = ntoh(k[1]);
+ I1 p( d. g- w e" t' b0 C45 register ulong c = ntoh(k[2]);
+ O ^; H: F% a46 register ulong d = ntoh(k[3]); % y2 S! H J6 L4 I
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
2 n! `9 R9 B: t9 w5 E" F48 register int round = _round;
0 B& i& A, O1 w3 a7 |49 register ulong sum = 0;
+ K1 X0 S1 v% T, h: i50
. m+ _6 S8 y& z( q+ N51 while (round--) { /* basic cycle start */ 4 Q) t: c+ R, B' K
52 sum += delta; $ b6 ]' T( j: o# @
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
A9 E$ m( j& E' A1 E; k9 ]+ J54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
9 I. i p& ^7 q6 r55 } /* end cycle */ 0 _% `7 O+ n$ \2 e$ y* C' `
56 out[0] = ntoh(y); " [! j+ W r: X3 ]" |
57 out[1] = ntoh(z); * }6 j. k; C! b
58 }
3 w! v) F( ~ M8 J3 j" f0 D, _59
4 m" ]5 J1 t/ J2 S @3 j" L60 void TEA::decrypt(const ulong *in, ulong *out) {
# C3 R! B' n8 `( u61
( z% e# z) s; j+ K, z3 k- T0 |62 ulong *k = (ulong*)_key; , l- Y# D% N; f/ I+ Q! m
63 register ulong y = ntoh(in[0]);
2 N x! O' q+ U0 |2 l* A64 register ulong z = ntoh(in[1]);
2 f# m9 u% n3 U+ S% T4 A Y65 register ulong a = ntoh(k[0]);
. W6 }7 r" A& \" _: h( V. y! b5 r66 register ulong b = ntoh(k[1]);
, y9 @8 x( l% Y* w- E4 d( I/ M67 register ulong c = ntoh(k[2]); . l- h& E$ C7 E" N. U& y3 [
68 register ulong d = ntoh(k[3]);
* Y/ ?. h6 R5 C' A6 D& H69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ . l+ ^% A3 U+ s: n
70 register int round = _round;
3 m( i" ^: l# ?71 register ulong sum = 0; . Z! Y/ w# t/ G
72 " ~/ s; U- V% S. }
73 if (round == 32) 1 t$ ~" [+ p: m# o
74 sum = 0xC6EF3720; /* delta << 5*/
- c7 @0 u# D1 n# A" W! Y75 else if (round == 16) 2 [0 h* [. H7 V1 I
76 sum = 0xE3779B90; /* delta << 4*/
: [% K! u4 I* l# s2 d' {( L: X* E77 else * J; G- Y2 v+ l0 B/ f
78 sum = delta << static_cast<int>(logbase(2, round)); 8 _7 v% `/ ^6 z: @4 @% k4 G6 }4 ?8 O
79
5 `2 l1 E8 C8 T& j" z7 y80 while (round--) { /* basic cycle start */ ( ]- [( y0 m! a
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
: s, A( F+ ~' I# r82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); ! W( x; Z1 t" ^# w
83 sum -= delta;
3 Q5 J n" f# [- a84 } /* end cycle */
; l" {9 L/ _' I% |0 ]% ^85 out[0] = ntoh(y);
; ?% o! ~8 x9 C8 ~/ m3 o* Y86 out[1] = ntoh(z); ( I3 ~! F5 W6 x7 A1 m) y1 E5 E% F
87 }5 x/ O# k" g1 j+ Q& p
; |$ _7 q3 n. j& X# c0 T需要说明的是TEA的构造函数: / m; E4 x- Y p* F! p0 H3 G
TEA(const byte *key, int round = 32, bool isNetByte = false);
% j6 t! r2 ]) h+ N3 {1.key - 加密或解密用的128-bit(16byte)密钥。
1 N/ Z: I3 R% H5 O) a/ R+ t# [2.round - 加密或解密的轮数,常用的有64,32,16。
- w+ |( n2 s( F6 W; I, y3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! " p; h2 F8 a7 e) B
+ i/ V/ P8 q3 i: N! p最后当然少不了测试代码: |
|