|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
' R3 k1 l, H3 X3 R 2 #include <cstring> //for memcpy,memset
; _ @: `8 t5 V9 s+ K6 S 3 0 w: r [ E/ l; a
4 using namespace std; / A( c& n$ i7 L; C. N
5
7 |* f W$ p$ ^: @ 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
: L$ j8 u- I2 o5 P' Z- r& I3 r2 b 7 :_round(round)
; q: `% [8 d( {0 V 8 ,_isNetByte(isNetByte) { , L9 g$ @* Z/ d' b' J
9 if (key != 0)
" F9 P3 X w& v0 M10 memcpy(_key, key, 16);
9 n. B% I: @% T/ N5 e7 h. T* n5 j11 else
! k, X: I$ r/ |% J7 \& s9 b7 C9 S+ ~1 R12 memset(_key, 0, 16); 8 G0 K5 _: T' R) D! r5 x a
13 }
3 v+ L( `1 Y6 N! j4 |- |14
! i& r' R ~3 u& X; q {5 F15 TEA::TEA(const TEA &rhs)
/ \1 W) B. C: t, @16 :_round(rhs._round) + l- s( n' K% ~4 C3 O* `) ~. m9 W6 T s
17 ,_isNetByte(rhs._isNetByte) {
+ r+ F& p4 M+ t# T* V18 memcpy(_key, rhs._key, 16);
G5 \# B- S6 t0 Z7 @# `1 m9 d19 } 1 M* T9 W9 n3 x! S
20
7 T3 ~% H0 x# L, `, I$ q21 TEA& TEA::operator=(const TEA &rhs) { 0 z3 Q9 d) g& j A# H" Y1 H
22 if (&rhs != this) { 7 k& ]* u0 O* T7 d: Z, E
23 _round = rhs._round;
1 X' l3 E" M& x' A, B24 _isNetByte = rhs._isNetByte; / @8 b9 y4 F$ N6 J0 _$ W
25 memcpy(_key, rhs._key, 16);
9 K( O, }9 k5 y26 }
, e" @% e( x! i8 t3 {27 return *this;
9 n) t; y, H' F& ?2 |. Q$ j# `28 } ) l% ^7 r* {) g( d! S" U! o
29
U9 ]0 g3 l! R1 c! k, |, {5 y30 void TEA::encrypt(const byte *in, byte *out) {
# v) n. m% P1 `- o" H5 T% X6 F31 encrypt((const ulong*)in, (ulong*)out);
. k( {/ Y' Z0 `' y0 Q32 } 2 ?( |) W% g' r `- |
33 $ G# f5 b+ A ^5 i6 |7 g
34 void TEA::decrypt(const byte *in, byte *out) { ( l( H/ Z+ Z8 I3 J7 b
35 decrypt((const ulong*)in, (ulong*)out);
$ d2 C8 K; _- J% |36 } ' t/ T6 |6 N8 O+ a( J
37
" v/ l# _# z. {! ~% N38 void TEA::encrypt(const ulong *in, ulong *out) { / |& i$ n8 }% L; e. _( O' w
39 : L* s8 y3 k- a+ S; p
40 ulong *k = (ulong*)_key; ! L8 @2 T" b: T$ Q5 q0 D
41 register ulong y = ntoh(in[0]);
1 U! V# A! H3 i/ b42 register ulong z = ntoh(in[1]);
/ g0 O6 [$ i. ?43 register ulong a = ntoh(k[0]); . l9 ^% `: C [, Z# M6 t# {
44 register ulong b = ntoh(k[1]); 2 x* t+ y2 {+ Q6 `5 B G6 d: d
45 register ulong c = ntoh(k[2]); ( s* y9 d/ I$ a- |' x* R4 g/ @
46 register ulong d = ntoh(k[3]);
b. Z2 ~$ k( P# r1 N% c3 U$ |47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
: c3 Z9 A7 P" O+ t; s48 register int round = _round; u4 p2 S6 n* E+ w" `
49 register ulong sum = 0;
" ^% K" g& z* v4 p50 & q7 B2 | M# N2 u O
51 while (round--) { /* basic cycle start */ 3 k, A0 h* F4 E5 ]. r( Q( e
52 sum += delta;
5 @$ X1 b7 g# Y0 H O53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
, G' p; L% @- ]( F9 C5 e54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
# l# C: P; m6 d y: ?: n8 j1 g55 } /* end cycle */ . ] u9 C; R: j/ c6 Q) c2 n
56 out[0] = ntoh(y);
6 k( c6 [2 E( A# G$ p1 k57 out[1] = ntoh(z); . ~0 g; o( v$ j, a, D) b, P* s
58 } . Q* Z+ Q* j2 ?, h9 ~
59 3 a" a: }# ~; a! M. V: r. Y/ O
60 void TEA::decrypt(const ulong *in, ulong *out) { 7 C' c' h. H# v1 x& Z
61 ! D. e2 ^+ _! B9 }
62 ulong *k = (ulong*)_key;
) y% C/ M3 L' A. R0 i63 register ulong y = ntoh(in[0]); 0 g6 {8 j/ z! L) [
64 register ulong z = ntoh(in[1]); / j% s& _$ n# n) c" U
65 register ulong a = ntoh(k[0]); % x5 w8 {. k% x/ }- Z- [' Q
66 register ulong b = ntoh(k[1]);
; q9 m. Q4 p, A# c ]+ _! w. s" a6 |67 register ulong c = ntoh(k[2]); / [5 j/ y# H* Q' m& Q1 p
68 register ulong d = ntoh(k[3]); & M' v* \0 o* c) A+ {, l+ A4 j+ N1 m
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
5 D) J% b, {* b70 register int round = _round; 3 }9 v4 N$ h1 P
71 register ulong sum = 0; # B. b8 }! |8 l7 q% N( j3 f
72 : x+ A9 F- q* |/ `
73 if (round == 32)
; `7 `& C$ e# h) H" {74 sum = 0xC6EF3720; /* delta << 5*/ 3 {9 X. r: a$ k+ d7 X, o
75 else if (round == 16)
: _$ @0 p0 x* G: a4 m9 T# H& {76 sum = 0xE3779B90; /* delta << 4*/ - t f2 X: U: f1 E$ V& x/ S ~
77 else - R( [- h' C% h0 z- ^: x
78 sum = delta << static_cast<int>(logbase(2, round)); ! M6 k+ B% M' ]8 A
79 8 M0 \+ K6 z% o
80 while (round--) { /* basic cycle start */
/ @0 S/ o* K) O& ?4 r& ~, F/ R# w81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
7 R7 `5 i& j% J. c: ?2 a) m) r. F82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
6 d; j9 c+ o1 {7 b83 sum -= delta;
4 F8 n8 k7 o5 q: @84 } /* end cycle */ + W% \) f- d# P& Q6 i. Y) m
85 out[0] = ntoh(y); ; s8 U8 s4 J+ ^
86 out[1] = ntoh(z); 4 l3 w( `3 |1 T0 v
87 }& u- c7 w4 i0 _- O
$ S0 _! }2 x5 e0 i
需要说明的是TEA的构造函数: i; L3 Q0 I! [& p# l# g
TEA(const byte *key, int round = 32, bool isNetByte = false); ! X% J+ ?+ K/ Q3 Q L4 ]/ C9 [( C
1.key - 加密或解密用的128-bit(16byte)密钥。
) w( O* a1 b* Z$ ?5 _2.round - 加密或解密的轮数,常用的有64,32,16。 $ V1 Y8 U v8 d( Z- { b) o+ Y
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
0 K, L: ]2 h* d! m
. F( @$ H* K6 c1 J, h4 ]( U7 j最后当然少不了测试代码: |
|