|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
/ R' j3 h$ J" n& ]# ~ `, g/ \/ U 2 #include <cstring> //for memcpy,memset x6 h! b% t/ o1 ]
3
5 f. |$ v* B# P1 W: J 4 using namespace std;
% e0 U8 t' x( O, n% O! U/ P3 F 5 + W: S8 U; {) N; m/ j) K/ G
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) + `5 e5 J: G& B# u9 U3 i" R, l
7 :_round(round) ! S# P' t8 K4 |: U1 x/ i/ p* a# ^$ h% B
8 ,_isNetByte(isNetByte) { 3 h8 W8 w, _! l
9 if (key != 0) 0 N1 t* @* l( u
10 memcpy(_key, key, 16); - X7 k4 q5 a4 Y$ i1 U0 J3 P4 m/ W
11 else
7 q% E& [/ t3 u" Y: G12 memset(_key, 0, 16); 2 \& T6 a- z/ @+ m/ l
13 } " q! `, G0 W M* ^1 u$ ^# D; X
14
\3 v# Z8 K1 C15 TEA::TEA(const TEA &rhs) 2 }# a+ F4 ?8 V3 k
16 :_round(rhs._round) 7 q+ j6 i; b0 }$ A* o' |9 k' X
17 ,_isNetByte(rhs._isNetByte) {
+ i! s' A( Y- z# k& L' O; F9 j" Z6 J T18 memcpy(_key, rhs._key, 16);
9 ]4 r/ O' p, h7 P# o+ O19 }
' b( C( l% L% r! c0 ~8 O$ s20 + p5 r2 O2 w/ a- u
21 TEA& TEA::operator=(const TEA &rhs) { ; `6 H4 g6 i/ R
22 if (&rhs != this) { $ i& p2 J3 D5 J. [& i' ?
23 _round = rhs._round;
! |6 F# j p: I7 _5 n& f& `24 _isNetByte = rhs._isNetByte; . p- {8 t4 q- B) g0 I
25 memcpy(_key, rhs._key, 16);
- p* ]) }; ?9 }, P4 z. m26 }
' {/ B3 V1 ]% K1 S1 {( w7 V# h8 z/ m27 return *this;
) ^3 @/ ]4 D0 Z) r6 E# b6 h6 g* `28 }
9 n. B+ L# b2 j1 S: u; @$ O29
. \# f: K4 t, Y, H$ D30 void TEA::encrypt(const byte *in, byte *out) { ) }9 Q/ |5 r# V: s
31 encrypt((const ulong*)in, (ulong*)out); % o3 O/ F; {0 j+ E* E! t; j) s" A9 ^' W
32 } 7 q/ c! B% p3 P% e
33
* l& F4 q/ g/ ~' c34 void TEA::decrypt(const byte *in, byte *out) { 3 j( @, m! X# T7 C
35 decrypt((const ulong*)in, (ulong*)out);
/ L0 R2 r9 E2 y `/ w36 } ) {+ q! r) X! b
37 9 S' R, b; q, q( @' Y
38 void TEA::encrypt(const ulong *in, ulong *out) {
) P( \: v* U6 K; h39 8 ^1 h2 N$ @6 V% [' ?7 P1 o
40 ulong *k = (ulong*)_key; / D3 x5 a1 K$ x2 n* B7 V
41 register ulong y = ntoh(in[0]); $ B: N+ q( [" \2 G! P2 g9 D" v, v
42 register ulong z = ntoh(in[1]); & u' E8 P( n0 }$ w7 g8 P
43 register ulong a = ntoh(k[0]);
) E6 S7 R3 |& b" m6 G, L7 s# j7 I44 register ulong b = ntoh(k[1]); / h5 o ^& M2 B9 P5 E B; l
45 register ulong c = ntoh(k[2]); 8 t$ `) ^1 l, t) A! L/ z
46 register ulong d = ntoh(k[3]);
7 Q/ T! o; [" _- L- e47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 8 r: f3 u. j6 \* o# U! `1 f
48 register int round = _round;
/ l* p8 b8 X% V1 o49 register ulong sum = 0; ' J/ z; g( q( S9 N
50 2 F+ y/ C7 J- z) J" U# ^! q
51 while (round--) { /* basic cycle start */ & u2 Y+ B4 R0 L$ T4 L
52 sum += delta; " [5 ^3 B8 }2 p: [2 O o
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
' I! s5 D# w/ N* ^( U; N54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
4 W; h; ~1 Q8 g/ |55 } /* end cycle */
& J2 |1 Q+ w! I& _ g56 out[0] = ntoh(y); 5 Z' B% c1 t# ~
57 out[1] = ntoh(z);
" m- B0 ]$ o" k5 C2 E, S58 }
! U5 v M" T" i59 5 f# p0 m x6 s2 N4 Z6 k0 U# w6 w: p
60 void TEA::decrypt(const ulong *in, ulong *out) { 2 q5 H8 o" z" n, \9 Y9 W" A
61 2 _+ \% g4 H4 K* Y
62 ulong *k = (ulong*)_key;
/ ?! u# M( ]6 s5 k0 ?; e63 register ulong y = ntoh(in[0]); 9 V: k0 h8 T) r8 W
64 register ulong z = ntoh(in[1]);
5 n3 j% e; P0 j$ M, K65 register ulong a = ntoh(k[0]); ; q2 u' I) h# {$ Z
66 register ulong b = ntoh(k[1]);
& K$ Z- y: z7 ~' A8 U+ y2 T4 X I67 register ulong c = ntoh(k[2]); ' `6 m! D3 K; c9 W. _9 w, o
68 register ulong d = ntoh(k[3]); + }6 Q, H! P* I* V i
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ $ ~7 l0 X9 n% t! m q: ?
70 register int round = _round;
9 q W9 b) b- |$ |1 y( X0 m2 p71 register ulong sum = 0;
# A. q) l/ T5 g( t6 F72 & v4 W. ?8 h7 S+ X a9 T% Q" V
73 if (round == 32)
R; K% _/ m3 p, ?7 _74 sum = 0xC6EF3720; /* delta << 5*/ ) U# E& R& W" |( ^
75 else if (round == 16)
3 q3 V" m7 }8 V76 sum = 0xE3779B90; /* delta << 4*/
( d, |5 u- Q" S, N! S; M$ |/ t. n$ e77 else 7 D9 B ~2 [" ` W, v& O9 [
78 sum = delta << static_cast<int>(logbase(2, round));
$ {3 h8 G3 m; |3 k6 g79 7 D/ x, S8 n! H8 {, v- f( H$ D
80 while (round--) { /* basic cycle start */
- |! {: O* S4 b" F81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); $ ~4 c1 g F" r( H0 e: q, y
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
% P0 @) F+ m- ]" J) {83 sum -= delta;
! q% ~+ j- `# t2 P, v% H( q84 } /* end cycle */ : J# @4 a9 }/ w: Y+ a# m$ Z
85 out[0] = ntoh(y);
R( Z# u+ {/ K9 ~, ^# A+ b86 out[1] = ntoh(z); 9 h% i- {' P2 Z
87 }2 _! U& k" E$ X1 Z0 T
: |2 O) a; u+ l* l6 K需要说明的是TEA的构造函数: ' k- [. {& K7 f* [0 {( E# j
TEA(const byte *key, int round = 32, bool isNetByte = false); ( F7 B% O- Z+ e1 H% v
1.key - 加密或解密用的128-bit(16byte)密钥。
- s% }& d3 l/ T! ]2.round - 加密或解密的轮数,常用的有64,32,16。 + Y# J' L$ i1 I- U# m
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! K9 H) c% R+ u f2 p/ H
# n' ^5 J2 Q G# }" s3 ]6 k+ s
最后当然少不了测试代码: |
|