|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" 9 I2 d- A* j5 t+ {
2 #include <cstring> //for memcpy,memset
* a# H4 R. s5 }$ M# ~$ A 3
) y! M0 [$ ~* f4 Q7 y 4 using namespace std;
1 B& G6 B4 Z* p 5
% m7 i+ u4 d! B) V' Y 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) . [- |) i) H: l& k0 b% m
7 :_round(round)
' R' F1 {! j9 v$ \# @4 @ 8 ,_isNetByte(isNetByte) {
6 s# M1 A* d6 O 9 if (key != 0)
# R$ w7 I9 `& k* J1 q1 y i+ Y$ V10 memcpy(_key, key, 16); - k7 Z! F, R5 h. n" _
11 else
+ `& s# d- u3 ^6 K5 U12 memset(_key, 0, 16); : ?6 u& b7 z* _! m( S$ F+ m: l0 @
13 }
3 s$ k9 S: s8 h& ?14 8 ?& @; f) a* w( g2 F. D
15 TEA::TEA(const TEA &rhs)
# W* l5 s# h# ^0 x- `4 h16 :_round(rhs._round)
2 A' K7 ?$ E) Q8 o9 {2 J4 z# D& U17 ,_isNetByte(rhs._isNetByte) { * f! s8 Q, a P$ ^
18 memcpy(_key, rhs._key, 16);
O: d6 L% v, ^19 }
2 b- w9 U8 b) l/ O20
+ X) o5 S3 W3 Z; v; o2 w21 TEA& TEA::operator=(const TEA &rhs) { 7 X b1 D0 E+ y1 J- U
22 if (&rhs != this) { ( n' @0 _0 e' Y$ w ~1 G. i" s
23 _round = rhs._round;
8 | \1 f- p2 S; m5 N24 _isNetByte = rhs._isNetByte; , Y3 [, J+ I$ [
25 memcpy(_key, rhs._key, 16); 6 R0 V5 a, D' v. G
26 }
) E' f3 G, J/ p4 d: ?8 j27 return *this; 4 _& P9 `+ _" [6 v4 p A6 S
28 }
5 _2 y1 F0 B6 W& J4 i" K29
' [1 i( Q; x3 |4 E" x+ X30 void TEA::encrypt(const byte *in, byte *out) { 3 E+ A' q. D$ ~; i* H" N! O
31 encrypt((const ulong*)in, (ulong*)out); , D; B; c& Y; ?6 Y* p4 @
32 } 8 T7 {# m# k W9 B7 s; D
33
* Y" @6 [1 A0 J" l+ O34 void TEA::decrypt(const byte *in, byte *out) { # D+ }6 Q& [& h: e( K
35 decrypt((const ulong*)in, (ulong*)out); 0 R' o1 i8 ?+ M- d# L! F7 y
36 } ( c9 e( v6 T* k9 ?
37 : R4 |/ x: [. p2 z# e1 |
38 void TEA::encrypt(const ulong *in, ulong *out) { 6 g* z9 |" F, h; e' ~4 S
39
) O" m0 x7 q1 k% C7 u+ a$ C40 ulong *k = (ulong*)_key; 2 b& J. c1 }0 M* a; H, e" e9 D* K3 e
41 register ulong y = ntoh(in[0]);
/ \9 x9 ]( M3 ~3 t2 y42 register ulong z = ntoh(in[1]); 5 h7 V' @! u$ C" ]1 }9 X ?
43 register ulong a = ntoh(k[0]); ; O3 ^+ T% }: }* b
44 register ulong b = ntoh(k[1]); 5 A% Q: e7 |- [3 i* M3 E& m
45 register ulong c = ntoh(k[2]);
/ C+ ]$ A: P, Y46 register ulong d = ntoh(k[3]);
; ]! M7 s9 h3 H& _3 |47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
1 H% E( @8 Q0 X) S48 register int round = _round;
8 e4 A0 m( s) g& j# @49 register ulong sum = 0;
. ~* y( H% {& y7 i5 |* R50
+ V# S7 q; `' x/ w; {2 u9 @. E51 while (round--) { /* basic cycle start */ Q* X- v. `* F# I" h
52 sum += delta;
1 x# U( j& ~/ t' g53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); ; p; N8 P4 U$ m s% N8 t* A. W0 `
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); y+ n/ X1 `" O6 l5 N; t; }# G; p4 s, c
55 } /* end cycle */
. `+ U8 S2 t; k: y! Q& R0 j. x56 out[0] = ntoh(y);
`: c' T9 B' ]57 out[1] = ntoh(z);
5 A" w8 c6 M& F( j" O58 }
2 N' q( m) n; `6 f# U59 : h5 c- K% y7 H: q6 f3 W4 `; _
60 void TEA::decrypt(const ulong *in, ulong *out) { , `: m+ F! C K/ P) L" C
61 : t A0 K; B. Y2 P) Y: E
62 ulong *k = (ulong*)_key; $ _" r2 c6 R$ M, R5 x" p i
63 register ulong y = ntoh(in[0]);
2 f- {, b# _, W- O' F0 ]64 register ulong z = ntoh(in[1]);
; x" J: g$ F+ ]65 register ulong a = ntoh(k[0]);
|# P3 m- Q( @, N- L2 `- A66 register ulong b = ntoh(k[1]);
, T$ w4 n. u9 ]1 p% E+ R67 register ulong c = ntoh(k[2]); 4 [ K% ~6 ?$ q* K9 B/ g9 p/ y
68 register ulong d = ntoh(k[3]);
. A0 \$ r7 j Y; d69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
" N8 R# n+ B' w- ]+ a1 o70 register int round = _round;
$ c% a4 n9 z4 W; `) f B/ L7 t6 G71 register ulong sum = 0; - N3 P! ~+ f. m
72 4 R: y: Y8 }0 B3 }# Z) f
73 if (round == 32) 2 Z# q) S* z. E3 ^' E5 V
74 sum = 0xC6EF3720; /* delta << 5*/
- E. L# M# b6 T5 D$ V, f2 C- }75 else if (round == 16) * d! G0 }8 Y( J3 E4 e
76 sum = 0xE3779B90; /* delta << 4*/
% U* d5 j, m/ w- R: J* o+ r- ^77 else 9 K# X/ e& g3 C- |$ y% r
78 sum = delta << static_cast<int>(logbase(2, round)); % I& O' ~, p- u' {; b' v
79 0 z& m. y" ?( N% _9 t
80 while (round--) { /* basic cycle start */
! j7 D$ v5 }) a81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
9 @3 S; m; K+ k. c% }5 d82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); ( I4 E& s I1 ^# {- x
83 sum -= delta;
' V- G% J; f2 n! {8 S6 }84 } /* end cycle */ , o5 [: G+ o2 Z" f, m
85 out[0] = ntoh(y); e: A P3 \4 P7 n
86 out[1] = ntoh(z);
. t* Z) A4 \8 L5 J87 }
. l5 b2 g; _! |8 y
/ S6 y' d/ f2 b% u+ e& o7 s+ k需要说明的是TEA的构造函数: 7 ]" j) v! D/ l) J" X( j9 q: p
TEA(const byte *key, int round = 32, bool isNetByte = false); 2 H+ Q+ W3 m3 v4 j6 Y
1.key - 加密或解密用的128-bit(16byte)密钥。 " e: u$ _, C+ ?
2.round - 加密或解密的轮数,常用的有64,32,16。 ( H9 r# U+ H8 \0 q( ?1 D
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
; r. }: q- A- r# B2 \# h# ^
: t% o4 J* C" N" s" g& ^& T最后当然少不了测试代码: |
|