|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
3 |1 I4 a2 I& m8 M+ @; f* D+ T 2 #include <cstring> //for memcpy,memset
. M; B; g8 I1 L, k" R 3 . c# W; ~7 y* D, |; F
4 using namespace std; 7 t7 ]$ x2 a) {
5 + K- E* t7 b ^$ s7 ^
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) + k4 o9 R5 d% P0 b) s
7 :_round(round) : Q. j' W4 J; L6 {
8 ,_isNetByte(isNetByte) { / `! g' }; F w4 S. y
9 if (key != 0)
! r: s# O2 X; r( j3 \5 @10 memcpy(_key, key, 16);
7 [" `0 a7 b) y+ g11 else 4 n6 N8 B2 ?. ^: b9 E
12 memset(_key, 0, 16); , ^- I; h5 S7 C2 q
13 } # F' v8 ?2 l& w& O1 N! x
14 0 ? I# T" I6 x* M, G0 ~
15 TEA::TEA(const TEA &rhs) 1 B, s S2 C" h- @& D
16 :_round(rhs._round) ) H9 ?2 o+ h. I& C
17 ,_isNetByte(rhs._isNetByte) {
/ ], W7 c" H. @18 memcpy(_key, rhs._key, 16); ; _1 Z9 n' ^8 @2 ^
19 }
: m' L1 n2 u# |: Q! Y0 S/ l20
5 `: h6 }* K/ ~- D+ m4 F21 TEA& TEA::operator=(const TEA &rhs) { & c1 b- z3 y- C
22 if (&rhs != this) { ; L% Q- S" V5 g' t7 _: ^
23 _round = rhs._round;
0 E& T% M( y6 {# a H w7 h24 _isNetByte = rhs._isNetByte;
" G% ]! u# b7 Y* Z. [ h+ o E25 memcpy(_key, rhs._key, 16); 1 Q/ Y; Q& q6 `& H* |7 W+ `
26 } 6 ]/ Q4 o( |' ]+ M
27 return *this;
$ ^: m. Q$ A, ^( y8 j28 }
/ H- d5 h& r) G* k5 R29
. \ W2 g" f/ U6 g8 j30 void TEA::encrypt(const byte *in, byte *out) {
8 \: g2 g+ {( Z; b31 encrypt((const ulong*)in, (ulong*)out);
! B9 V* c0 v7 J' a! j32 } * b- V3 `% r0 g% ^6 ?* e- J
33 2 Q( T+ V) }9 p U
34 void TEA::decrypt(const byte *in, byte *out) {
8 \, D- l4 q+ g7 s$ e P35 decrypt((const ulong*)in, (ulong*)out);
x9 p3 s1 ?# C" X9 d36 }
. }, r1 l& I, T; E/ g8 J. J37 8 }* L2 ?2 U8 e
38 void TEA::encrypt(const ulong *in, ulong *out) {
( t7 a. C) l: P Q- l5 x5 g39
$ f. K* l$ E2 r% p( G* m40 ulong *k = (ulong*)_key; 2 x/ O Z7 M4 M1 x" K9 A% j& K8 u3 U
41 register ulong y = ntoh(in[0]);
& @: x) Y) V) \: S42 register ulong z = ntoh(in[1]); 3 D" \3 y1 s0 }2 U* }
43 register ulong a = ntoh(k[0]);
* u4 S) D% j, a3 f Y44 register ulong b = ntoh(k[1]);
i& g0 o; b' `1 K' L! g6 n8 Y45 register ulong c = ntoh(k[2]);
; m6 j/ K5 @) ~1 e, D46 register ulong d = ntoh(k[3]); , V$ F# X+ E, [3 u# n1 z
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
! }, E0 j+ n; t, {9 X8 D$ k9 I3 Q48 register int round = _round;
( D* B0 p4 h5 z49 register ulong sum = 0; . z; {9 [4 T" v8 d
50 8 C6 e: b7 G) c* V% F) D
51 while (round--) { /* basic cycle start */ 4 U' ~( ^: O: u6 P% |
52 sum += delta;
0 n) U6 O/ L7 x6 [# a/ c# R3 o53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); ' d. {9 O! u; [; N6 T, x- f0 K4 \
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
9 v. Q! Z* s F; i9 f55 } /* end cycle */
3 k7 R, r8 K+ B# u$ Z6 l6 ^56 out[0] = ntoh(y); ; _5 ]2 a# R: Z+ T; ~3 R
57 out[1] = ntoh(z); % u+ S3 P- N$ a1 t9 s0 {" |1 ~
58 } ) h5 B# F; ]6 t* I
59
( j7 P* {# E& [& b3 z60 void TEA::decrypt(const ulong *in, ulong *out) {
1 [9 E7 ]: W p: G9 s! {. t2 o; J61 9 z2 s6 i5 u# y5 u S- C
62 ulong *k = (ulong*)_key; : z/ E1 M" Q( W- V) O
63 register ulong y = ntoh(in[0]);
+ r" ~" A7 J* b; I) R64 register ulong z = ntoh(in[1]);
& l& }& n8 n$ F% U& L6 k65 register ulong a = ntoh(k[0]); m4 `4 b1 R8 m, H0 J
66 register ulong b = ntoh(k[1]);
' H/ s" t8 I. ?! i" w67 register ulong c = ntoh(k[2]); 9 r! J; E3 g3 V9 w& a& {" [
68 register ulong d = ntoh(k[3]);
6 W# T/ w2 A) e7 Z9 ]1 J3 s69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ . Y" A+ I+ C% U! v3 }6 U7 @
70 register int round = _round;
$ Z$ ^5 {1 n" [% _. H8 }4 |71 register ulong sum = 0;
* K2 e+ Y( L$ A$ |0 ^72
+ r) ]5 H/ z6 L: r73 if (round == 32) * g+ D) V# b4 {& W; E' W+ z
74 sum = 0xC6EF3720; /* delta << 5*/
' B" \. b# g7 j8 O; w! T! b75 else if (round == 16) $ w: v" y8 r: `* _1 W
76 sum = 0xE3779B90; /* delta << 4*/
9 `2 a$ {8 O8 j+ ?77 else $ a2 [" |9 x' E, K7 z2 G7 d' T8 B; o u
78 sum = delta << static_cast<int>(logbase(2, round)); 3 a+ p8 H7 _& H4 X* N' ^5 c8 d
79
5 Y0 Q/ C& q6 U4 n6 k( n+ X80 while (round--) { /* basic cycle start */ , r/ r( v5 }+ B" ^" f0 g4 [0 y7 `; j
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
s+ M X9 ?# `' d. W' E82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); S1 c, S# [1 R3 H
83 sum -= delta; * S$ N; z' c2 N5 a
84 } /* end cycle */
: x# ?! i! T' {3 J85 out[0] = ntoh(y);
) S) V+ M* d6 m86 out[1] = ntoh(z);
/ g ?5 Z: F0 r$ `( A3 _8 \87 }
3 n2 G" d1 f6 b) j2 p' N" L0 l1 }4 Q
需要说明的是TEA的构造函数:
0 t) \& X: {) u; v Y$ ETEA(const byte *key, int round = 32, bool isNetByte = false);
& D7 A' `5 P6 v3 m/ y4 {' _$ ^1.key - 加密或解密用的128-bit(16byte)密钥。
' p2 f* ]' `# e7 m2 G2.round - 加密或解密的轮数,常用的有64,32,16。 M. N6 G" B! i
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! 6 \; h& Q% o4 o4 O u, b8 E
5 O9 ?) h. g$ H$ _' P8 l/ w最后当然少不了测试代码: |
|