|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" # h- K# J6 C9 A- O. v- ]
2 #include <cstring> //for memcpy,memset
) d' C* P2 }4 P* [ 3
, B( @2 [9 i, S 4 using namespace std;
# R( v8 L$ y, b# U5 G4 O 5
: w/ e( f( V3 a$ L) {; ? 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
& V" E; p A4 C+ {! P" l 7 :_round(round) $ C8 U+ s4 {- N# l9 }! x* p, i
8 ,_isNetByte(isNetByte) { 5 x: F6 N8 H8 T5 D7 K0 `
9 if (key != 0)
( M/ d# p1 ]: u" b7 i10 memcpy(_key, key, 16);
2 ]! v4 D( b" B3 g11 else 4 j3 K- K+ m# J9 \4 N8 @+ A
12 memset(_key, 0, 16);
* B, P& [0 L# n. u13 } 1 {& K( N1 l3 G& p
14
2 ]; a0 d( T* j7 ?9 k( l4 {15 TEA::TEA(const TEA &rhs) ) J) p% N$ X" v8 u* Z3 ^
16 :_round(rhs._round)
. I" p- w7 P6 F2 g: `8 \17 ,_isNetByte(rhs._isNetByte) {
# C7 j) I& z; l7 l8 t18 memcpy(_key, rhs._key, 16); ! {6 \4 Q. v! ^/ e# _; ^4 d
19 } D6 Y# X5 a% L1 [6 [. K
20
3 t8 H/ m+ G% p' B* u: _& d& C21 TEA& TEA::operator=(const TEA &rhs) {
+ p1 \. g4 u* l$ v0 X3 H22 if (&rhs != this) {
* `( p6 |1 g5 G" P9 p23 _round = rhs._round; ; t6 B8 h/ z# C; `2 e) R' [
24 _isNetByte = rhs._isNetByte; $ K0 c3 r6 l v* t5 [
25 memcpy(_key, rhs._key, 16); 9 t9 E' ~- E; V; k3 v2 S
26 } 0 x. p; k2 q2 o% u, F
27 return *this; 5 x8 t! B8 s' @0 V
28 }
# `: r! }7 X% b5 ]6 p8 |29 9 c3 R, _4 L* W8 l
30 void TEA::encrypt(const byte *in, byte *out) { * ?' J+ X% g% Y# ^4 i8 a
31 encrypt((const ulong*)in, (ulong*)out);
( d3 s* t; R, H- a7 S32 } $ b: S7 Z8 |: L( Q5 p" z( Z1 d
33 2 V9 }3 _+ V. q& T: E5 e
34 void TEA::decrypt(const byte *in, byte *out) {
: J3 {$ r" ]+ T: o% G! a35 decrypt((const ulong*)in, (ulong*)out); : @. d# T( A9 M0 @/ u
36 } & ^8 A. Z' c' R A
37
# Q! B0 [, m7 i/ b, j- [38 void TEA::encrypt(const ulong *in, ulong *out) {
: g ?' U1 C! n39 ' c) n5 d: n, P; h4 C) l1 m
40 ulong *k = (ulong*)_key; * Y( D/ \6 r0 L5 K( v
41 register ulong y = ntoh(in[0]); . m4 b( u5 ~2 _6 A. K& u% F
42 register ulong z = ntoh(in[1]);
4 |' G3 W5 h8 l/ W43 register ulong a = ntoh(k[0]);
% }" X2 H/ y L; w44 register ulong b = ntoh(k[1]);
! c' I. w( U8 D" m* Q' g: d45 register ulong c = ntoh(k[2]); ; C/ W- X N) M
46 register ulong d = ntoh(k[3]); : E5 k- V! r) G7 }' q- u. `
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ : Q4 w$ n& i9 k/ W1 s
48 register int round = _round; ( U0 o) D& V6 c3 ?
49 register ulong sum = 0; / F- o R0 ~+ J, a; ^5 j$ d+ b: p$ Z2 j
50 1 w5 d7 C" T; }+ ~: m1 c' J
51 while (round--) { /* basic cycle start */
8 F0 X/ W! @# X2 F52 sum += delta; ' a. O' E* T( G2 D% Z" x' P9 T
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); ) C% X; f* V0 b/ L0 k0 U; b
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
! f6 _# A: m( F7 S55 } /* end cycle */
G% |" g# m" O2 f! N* Q1 r' a56 out[0] = ntoh(y);
$ y" D! w0 ?# D% p* \/ U57 out[1] = ntoh(z); / [7 e! r0 t- N
58 }
( ~1 m0 X9 f: l: N$ @59
: n D; l" }0 e. [( V60 void TEA::decrypt(const ulong *in, ulong *out) {
7 ]5 w2 o) Y) q! x" P6 z* H! W5 ]61
; z8 I8 t/ }3 n1 r% f62 ulong *k = (ulong*)_key; 2 _ m5 c* w; B9 V
63 register ulong y = ntoh(in[0]); ' H+ ^" i0 x, ~, w& k; g
64 register ulong z = ntoh(in[1]);
+ h# ?8 |; L- E5 k5 i65 register ulong a = ntoh(k[0]); & r. u" {2 K' ^6 _, F
66 register ulong b = ntoh(k[1]); 2 L: y0 k" }' r9 e
67 register ulong c = ntoh(k[2]);
0 D7 ^0 C$ o- R( ~68 register ulong d = ntoh(k[3]);
6 C. x4 H0 Y5 B2 z9 E- D. k3 {69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
+ L1 ~, J+ j0 d( M0 ], M70 register int round = _round; $ u- X8 k3 b. m' s/ d
71 register ulong sum = 0; 7 v* o2 d# ?# ]; N6 Q
72
2 k' c" r! k* B/ `) x. v73 if (round == 32) 5 G, m: I, m8 w- B$ h( K$ {
74 sum = 0xC6EF3720; /* delta << 5*/ 7 @: a- x5 c8 A; x: m
75 else if (round == 16) 1 W: I$ `0 E3 h+ ^# T
76 sum = 0xE3779B90; /* delta << 4*/ % l, x% Y& V5 S2 f
77 else ! @3 C$ j- N' O+ u. f
78 sum = delta << static_cast<int>(logbase(2, round)); ' i8 F+ L6 Z$ D) j( ?: C8 s
79
; u+ O1 ^3 h/ W4 V80 while (round--) { /* basic cycle start */ - j# U+ q! E% X' j
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); + Z$ t0 q2 R! [! W& L5 n) E" ]
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); # c3 z: f4 S0 B) \- Y
83 sum -= delta; $ \+ Q3 ^$ G1 k
84 } /* end cycle */ ' r2 o- ~; _7 F \: v, w
85 out[0] = ntoh(y);
; A) p: o9 \. T# K3 P- O86 out[1] = ntoh(z);
1 W" ]. t$ v1 c) P3 P8 g, v" s87 }% h8 G1 O& J, h5 S& o8 E
" t$ V) ^- ]+ g$ U; r/ t5 t1 _# [需要说明的是TEA的构造函数:
7 V# {: r6 v4 P2 UTEA(const byte *key, int round = 32, bool isNetByte = false);
/ I& ]) X& L* k& S6 L1.key - 加密或解密用的128-bit(16byte)密钥。
$ E8 r% ^1 u# g2.round - 加密或解密的轮数,常用的有64,32,16。 1 h7 R% N6 v0 ^1 t7 B c: F
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! + \4 Z; L7 K7 a6 [ ?
8 S# r& e" z* F
最后当然少不了测试代码: |
|