|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
! n8 u7 V6 T' g, C; U4 [ 2 #include <cstring> //for memcpy,memset # P! @& S2 |$ l7 X0 d( l- Y" t
3
" P f" `% h X 4 using namespace std; $ ]: V% s/ ~% H, j1 ]. n
5
; N t S5 v* R9 K- M- ? 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) H$ z# T, I N9 V
7 :_round(round)
6 A& R% w" v! L1 ^- W 8 ,_isNetByte(isNetByte) { / S6 z& Z6 c+ P3 ?# s! j2 W
9 if (key != 0) 3 J, M* f% k" S, X! h
10 memcpy(_key, key, 16);
8 b( W- B. S' s' a& S5 }) z- T: T11 else " h. O/ n2 `3 s; k- z
12 memset(_key, 0, 16);
9 \, W$ J/ k4 G" K5 @13 } ; F$ b8 H5 u6 Y) p2 X
14 5 B" e' B2 G, j+ m: r% H8 x7 G
15 TEA::TEA(const TEA &rhs) , j" Y8 e3 m2 d3 S: r% W! j
16 :_round(rhs._round)
1 X' p7 ]+ W- v0 v. s% H5 A% {17 ,_isNetByte(rhs._isNetByte) {
% @3 W4 }$ z; J& S0 F4 r( E, N18 memcpy(_key, rhs._key, 16); ; b1 B9 N( Q; P! g# ]
19 } + y; `! A/ T' [
20 1 N: b6 c: a3 B
21 TEA& TEA::operator=(const TEA &rhs) { 3 D ` U* c; ^& c2 R! ^4 _
22 if (&rhs != this) {
; Q' P! y. {5 R* R23 _round = rhs._round;
6 n2 Y! D% ~7 i% @24 _isNetByte = rhs._isNetByte;
; r% B# p/ `/ Q, T, w25 memcpy(_key, rhs._key, 16); " @; X) Z I2 K
26 }
" n. }4 X2 G: f! J/ K27 return *this; ; S/ w' [7 S& P" k
28 }
' ?& l6 w2 Z/ \- v- M: i- ?* Q29
1 U3 @! [* U" }30 void TEA::encrypt(const byte *in, byte *out) {
8 m, e% P1 S1 o" g3 J* N. H( C31 encrypt((const ulong*)in, (ulong*)out); 7 ]3 y- l; L* \- V
32 } / H+ z" ?/ t }$ x- N9 g
33
e- V% l$ R, Y) \. R) A34 void TEA::decrypt(const byte *in, byte *out) {
' l& c& H' e5 ~35 decrypt((const ulong*)in, (ulong*)out);
: `% v# l9 n: o. Q6 x. q0 z! p36 }
0 E" S& L) V- N }/ x1 G4 y5 f7 G37 9 F' d# K. \( B6 U2 r c! {* J8 T& d
38 void TEA::encrypt(const ulong *in, ulong *out) { % R$ L- Y" N, x& F2 Q$ f; \
39 ! f4 v/ H5 t1 c4 x$ T
40 ulong *k = (ulong*)_key;
6 `8 k& c: C: J41 register ulong y = ntoh(in[0]);
# [& F l, t8 ]& g42 register ulong z = ntoh(in[1]); % ~" O/ \: v0 I8 @6 U1 \+ D, X
43 register ulong a = ntoh(k[0]); + b1 B _2 U) j
44 register ulong b = ntoh(k[1]); 1 K9 k5 \1 N0 [) E1 j8 r! q
45 register ulong c = ntoh(k[2]); 5 R5 @- ~: K3 F( I) Y
46 register ulong d = ntoh(k[3]);
! g7 D. n6 [& h8 D$ V. B" ?# [# v47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ & Y: _5 g3 {5 Z, b7 s
48 register int round = _round;
/ p6 O {) O' Y u) X$ x- H49 register ulong sum = 0;
: q$ v- c- ]6 }6 B7 `4 R/ J50 1 H' }7 W I7 {: n1 H: ~
51 while (round--) { /* basic cycle start */ 9 v1 u3 v: b. ~9 a4 v
52 sum += delta;
0 }: @3 B; x2 m% \" W6 [ U53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
( \) R0 A. ^. f0 x. g. M. A& h54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); $ C& r! M& C; P. l
55 } /* end cycle */
5 f1 {1 i1 o( r56 out[0] = ntoh(y); : Q6 H8 T( \3 k B
57 out[1] = ntoh(z);
% y- `- [4 A' m7 ]& |- }& q58 } % ]! V9 Q- [0 E4 e$ \" _$ r/ E
59 % L0 o' |+ T F5 y! b T9 c8 K
60 void TEA::decrypt(const ulong *in, ulong *out) { $ L% N, ~7 }6 h5 S
61
3 v }$ n2 B3 J1 i" G: E62 ulong *k = (ulong*)_key;
% v5 j# ~! r7 S; Z63 register ulong y = ntoh(in[0]); ( w p- d! }2 H2 z
64 register ulong z = ntoh(in[1]);
3 Y% J$ y+ b* B9 A65 register ulong a = ntoh(k[0]); 8 x* w5 r6 m' k% U% w' J
66 register ulong b = ntoh(k[1]); k+ M- j8 Y: C
67 register ulong c = ntoh(k[2]); 3 v: v) C, q7 E" ~, s; Y+ L9 N
68 register ulong d = ntoh(k[3]); 0 v6 H+ t$ I y; V
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
2 Y" k) k- z+ L) L# `4 ~3 a5 s- U70 register int round = _round; P# M9 w% z) S7 `% {9 U* ~% r7 q# d
71 register ulong sum = 0;
6 s! ?8 m; M% ?" \6 O3 ^4 E72
5 {1 q3 n6 d- L( ~5 y: Z1 B73 if (round == 32) + A$ ~% Q+ V t4 p
74 sum = 0xC6EF3720; /* delta << 5*/ 9 n4 W# ]" d. b. U& M
75 else if (round == 16) ' F' }% x% E7 X$ E& ^7 ?
76 sum = 0xE3779B90; /* delta << 4*/
! r4 V8 z% x4 ~+ N" e5 M( t$ S7 `77 else + v& V8 A+ d- z# V j; \4 F; r
78 sum = delta << static_cast<int>(logbase(2, round)); $ R% Z( i- \9 W5 e6 l
79
% T/ L% j# F; u3 H80 while (round--) { /* basic cycle start */ 6 d7 J& e4 E2 n2 N( T$ B) i
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
9 ^ f& ]* p9 a" Q82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
9 E# i' C9 ]- R: y+ q& i2 t+ r83 sum -= delta;
5 S8 D5 O* _: k3 d! t84 } /* end cycle */
, l# k: `: z& F( g85 out[0] = ntoh(y); / P# G G+ v" n0 x/ a3 v8 {
86 out[1] = ntoh(z); ) l+ i! c+ L! y8 _8 ^
87 }
7 f" D6 L2 C! F) V8 `4 Q2 f
: o; `7 b8 u5 C# E需要说明的是TEA的构造函数:
( a. B- h& F& J4 H/ _TEA(const byte *key, int round = 32, bool isNetByte = false);
; z* y, d3 ~/ {5 l3 F6 s* z/ ?' X9 P1.key - 加密或解密用的128-bit(16byte)密钥。
3 K1 F9 Q# ~( ]# ~2.round - 加密或解密的轮数,常用的有64,32,16。 . |/ d' C1 }' X: x/ z4 |
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
! x! Z' S+ C7 _" V H0 t! h2 y7 `: g" Q) K! b- k3 s; ^
最后当然少不了测试代码: |
|