|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
5 t0 I- r1 \4 L# D( H v 2 #include <cstring> //for memcpy,memset ) k- L2 x! Q7 p& Q# c- I: W5 Z& c% @
3 / u4 L4 I9 k6 p/ _; {
4 using namespace std; 1 O* N4 B7 n+ X8 j {4 t+ B8 d
5
+ N# }) ?3 o! v2 @) a 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) 3 x9 M0 S1 G. W$ K4 E& L$ N" T
7 :_round(round)
( n* }, p: R3 u; B. C- l' } ?0 O 8 ,_isNetByte(isNetByte) { . t3 R# g0 j/ u; o3 F3 _7 L' b
9 if (key != 0) 6 H1 t# B8 Q" H' R9 U# G3 E
10 memcpy(_key, key, 16);
w4 g2 F; e$ |( c' l7 x11 else
" p, ^3 |" G& X/ m+ r, I12 memset(_key, 0, 16); * k, {4 e: }; l. d& h9 e- l
13 } & k, m& `" d( P. v" \9 g
14 8 B0 q y+ H4 K4 N8 a6 `
15 TEA::TEA(const TEA &rhs)
% u. d! j k+ ?3 t% e8 _! f16 :_round(rhs._round) 3 e8 [9 Q( b8 ?
17 ,_isNetByte(rhs._isNetByte) { 1 [! _. V" _* g0 d
18 memcpy(_key, rhs._key, 16); & K5 ~0 S1 Y6 R4 R% ^ [1 K
19 }
+ G9 O! J, \2 B. y# i4 x20
6 A0 ]- ]9 W( K, l B7 y% p21 TEA& TEA::operator=(const TEA &rhs) {
2 w, H9 M& L8 i" }22 if (&rhs != this) { M* m* i6 w( R/ v, K3 S; C0 n" |3 A/ w
23 _round = rhs._round;
! ~' K9 q* y7 _7 j4 J24 _isNetByte = rhs._isNetByte;
4 Z$ q( @) Z! b2 C) L/ g- G25 memcpy(_key, rhs._key, 16); ( D- q1 u# a4 R3 P. H9 E
26 } y. b' n& j6 a3 L5 j
27 return *this;
6 u: {2 k6 y X28 } 3 I( c$ R* n5 K
29 7 ?0 }) ?- `& y" Q
30 void TEA::encrypt(const byte *in, byte *out) {
- c( b% G' q& c4 Q( R h8 e! C31 encrypt((const ulong*)in, (ulong*)out);
; Q* `$ X- ~; r' q: p* E32 }
+ {( | O6 e$ ~/ y33
/ Z7 O# v! D$ A( O' o, z) h34 void TEA::decrypt(const byte *in, byte *out) {
1 t" D6 |4 q9 ?' P# C2 v3 J35 decrypt((const ulong*)in, (ulong*)out); - b* e% T; ?" L# l
36 }
- X8 _* ]3 ~2 m) k37 % R+ t* w( L! ?( E" k- X
38 void TEA::encrypt(const ulong *in, ulong *out) { * G2 _4 z# l2 z5 v5 E9 g& ]1 {& O
39
3 z5 I, Y4 B1 |40 ulong *k = (ulong*)_key; + L- ^2 t$ T' R, \/ f
41 register ulong y = ntoh(in[0]); * D' j% q. j7 U7 l F8 \
42 register ulong z = ntoh(in[1]);
' t9 n5 l+ f I8 {. @3 b/ h" F& ~43 register ulong a = ntoh(k[0]); " Z) E5 ~7 g( B& O* T7 W
44 register ulong b = ntoh(k[1]); , e W% S$ v+ }
45 register ulong c = ntoh(k[2]);
2 S: Y- r! l( L; }' o' o46 register ulong d = ntoh(k[3]);
) |" I! ^* a5 ?% |2 k4 ]" i$ b47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 8 U' v: L: N4 J( r* [" E1 `
48 register int round = _round;
- H& F( G6 V3 a49 register ulong sum = 0; % E) c- h& k( F
50
6 M* {' j3 f* ~/ W& P) I51 while (round--) { /* basic cycle start */ 1 h- J* d/ V8 {9 m
52 sum += delta; % Z; t, y( W; ~
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); 7 t* h5 _ _# Y3 u2 k
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
5 M+ Q5 m2 [6 M: g# k55 } /* end cycle */ / ?$ i6 H8 H5 I: X
56 out[0] = ntoh(y);
# _. v) w4 A3 T, J57 out[1] = ntoh(z);
- Y) J: p) A6 }! c! L0 g& L! L58 } . C- t2 I2 ?$ ?+ o& p( E: W- ~
59
6 ^7 X5 H/ i, l. N" D60 void TEA::decrypt(const ulong *in, ulong *out) {
* q: D/ s, ?0 Y# F- f: B61 ( H, |) A6 Z* F
62 ulong *k = (ulong*)_key; + T& @) _8 H8 I$ o
63 register ulong y = ntoh(in[0]); % [0 |- J7 e: B/ O1 z
64 register ulong z = ntoh(in[1]);
- d. }& d0 `1 c e6 S8 H65 register ulong a = ntoh(k[0]);
- I& a% E" c; c- H) o) U, {1 p66 register ulong b = ntoh(k[1]);
6 w3 x E' o. n7 y" U6 q4 X+ K0 O% Z- n3 R67 register ulong c = ntoh(k[2]);
# a' O& s3 |! D68 register ulong d = ntoh(k[3]); - @' C- ?! L- G- f6 e) l I
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 7 r8 k5 w* M. y+ z9 E) J
70 register int round = _round;
, f1 M$ e Y3 R) r+ J; f71 register ulong sum = 0; / I6 f: G! u- z1 [. R8 v1 O/ v6 D
72 5 t, c& e6 j7 M! U7 I& F) \% s
73 if (round == 32)
4 g6 q: Y) q% M! W: r! R74 sum = 0xC6EF3720; /* delta << 5*/ ! M# v1 A( U7 E$ n; P/ w$ d
75 else if (round == 16)
' o' J5 l0 X1 K4 V7 |! j/ f76 sum = 0xE3779B90; /* delta << 4*/ $ O) z# h6 n' ]1 i
77 else , `$ r1 [2 [4 M( {; a2 F& r2 x
78 sum = delta << static_cast<int>(logbase(2, round)); ' V0 t; Q" B" P5 Y3 H, `4 y, [
79
+ {( O# S4 V! j; M9 }% O% }80 while (round--) { /* basic cycle start */
* ^: r5 d$ Z: w! i# b81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
! h. U! y7 G1 q0 ^1 N! p, N82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
. |4 k; e+ @& a83 sum -= delta; 6 l+ v X3 Q5 k3 n5 Z3 i4 Q
84 } /* end cycle */ : P- d# Q; l, ~- {
85 out[0] = ntoh(y); I; E" N4 Z$ D8 m* o- P8 d! p- N
86 out[1] = ntoh(z); % |1 @% i; O d* x
87 }
7 P6 b6 s2 l* W3 w3 i) ?) W! N5 ~) H# h7 r6 l9 L P% S3 K3 p
需要说明的是TEA的构造函数:
2 e4 O4 Z7 [$ M( h' BTEA(const byte *key, int round = 32, bool isNetByte = false);
$ u( t& ^& L- ^. H w1.key - 加密或解密用的128-bit(16byte)密钥。
; f2 Q6 X/ t7 ~% S2 R2.round - 加密或解密的轮数,常用的有64,32,16。 % ` n1 k5 a9 u' k: J% }/ f
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! ) s! _& N6 o* V/ Q. g' }; k
' q0 H9 s0 j' h+ M. ~0 R) b" L8 B
最后当然少不了测试代码: |
|