|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" / ?5 d8 q- P6 [2 P) U; h
2 #include <cstring> //for memcpy,memset
+ Q6 B# p; z( j( u" p' [6 J _! ]( ? 3
4 k4 s2 v* N( k* ]9 \ 4 using namespace std; & j1 M: A3 H3 m! ]
5
& M* Y! D' y2 l7 g, F9 Z' O* d! x9 z 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) 7 N e( O: [; C o! p# F8 m
7 :_round(round) ; I0 H9 E# f! W8 J
8 ,_isNetByte(isNetByte) {
- Z9 f3 Y, [2 O 9 if (key != 0) 2 k. v: m- Q+ |+ [" @3 v2 P
10 memcpy(_key, key, 16); 0 {: t3 U: M6 U' o3 r
11 else / k% Y; a6 H5 F: z; {: ^$ V
12 memset(_key, 0, 16);
. l9 O* o1 V9 K13 }
: O2 C" v! V3 d& @/ ]1 t+ }14
& D2 a8 p* u1 L' d3 b15 TEA::TEA(const TEA &rhs)
% x% K/ C; V- s; D7 u& U16 :_round(rhs._round) 7 |6 J& }1 M8 C; z0 U i
17 ,_isNetByte(rhs._isNetByte) { 1 V% R7 l# c& M5 M9 ]
18 memcpy(_key, rhs._key, 16);
6 l8 W; R$ l8 H# d0 k3 A19 }
' w7 K& y8 _3 `+ j x* N$ N20
; a+ f4 h: Y/ \7 z$ U21 TEA& TEA::operator=(const TEA &rhs) {
+ C; P6 m0 B: x/ Q) a# Q# r22 if (&rhs != this) {
% [! g/ t( ]5 o# X& l23 _round = rhs._round;
2 d: R; s" [( i: S1 E: }2 n24 _isNetByte = rhs._isNetByte; 4 M% p' [9 y7 N) d1 m
25 memcpy(_key, rhs._key, 16);
# I, d) n7 u% C8 V9 W26 } , H' J# Q7 B9 d) i: V; i6 c% P! y
27 return *this;
2 i1 j7 t) Y1 ]/ `0 N4 D28 }
) C! h# B+ W {- W+ {29 ' Y( U: O) p+ k" O! l- {" h: k, v
30 void TEA::encrypt(const byte *in, byte *out) {
5 c: Z3 R: r& g5 V9 O31 encrypt((const ulong*)in, (ulong*)out);
/ a/ p4 g' |" o! x; i% E0 \3 ?32 } 0 W: n& G# |! f% i/ l6 b9 u
33
; S) r o/ { J; K9 k, {. f0 Z34 void TEA::decrypt(const byte *in, byte *out) { 2 C& @8 w$ O- h" b2 A" L
35 decrypt((const ulong*)in, (ulong*)out); : Z$ t7 z6 I9 a. b. h
36 } 7 n( }/ L5 J! [( \5 }& H
37 D* l5 Y7 Q3 x) b3 ?2 D' T( Z
38 void TEA::encrypt(const ulong *in, ulong *out) {
$ Q, d$ _* I/ Z! W39
# a& c+ I5 W) T% R* h& U40 ulong *k = (ulong*)_key;
( X1 f# V) `1 L! n3 {# p41 register ulong y = ntoh(in[0]); - T8 H, k+ w) N. u4 N
42 register ulong z = ntoh(in[1]); ) L, ]) @" [( V1 T
43 register ulong a = ntoh(k[0]); 4 S" K0 Z8 X1 a/ C+ O8 P
44 register ulong b = ntoh(k[1]);
$ u7 f+ Z3 \% Z45 register ulong c = ntoh(k[2]); # ^( _1 W7 _" O2 `0 W9 A3 g( T
46 register ulong d = ntoh(k[3]); 7 G, f7 d1 k( @" V% f5 \
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
^( Q( F3 \) |. @9 {48 register int round = _round; ' }2 O# i0 J+ J1 w. |5 \- F; @! r
49 register ulong sum = 0; . ]* t, i: U3 C, N1 }
50
+ A% R& N- h4 p6 n, v* U51 while (round--) { /* basic cycle start */ ' ^! j+ X* m8 ` r+ R& F
52 sum += delta; * y9 j( A% n7 o5 {$ E2 y
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
! G7 J* ?! U" C8 e7 W& O: t54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
4 b; P( L4 f7 H" C55 } /* end cycle */
/ f6 R! ?2 j9 {0 n7 S7 u% C( G56 out[0] = ntoh(y);
r( z2 m5 z# v57 out[1] = ntoh(z);
0 s. }3 q& u; B- i2 i& s4 ~4 M58 }
5 x# m. z) H( \8 n7 O% `6 g/ ]! f59 - ]( D1 y3 t& s; v5 U
60 void TEA::decrypt(const ulong *in, ulong *out) {
9 a; S- O* R) x* K0 t! z61 ' D$ A/ P5 i# N; W
62 ulong *k = (ulong*)_key;
. x; N) I$ ?% i8 r7 [! V& ^8 U63 register ulong y = ntoh(in[0]); / y& `8 g, C/ E3 ~
64 register ulong z = ntoh(in[1]); 9 W9 r8 U( P2 W
65 register ulong a = ntoh(k[0]); 1 c! F0 A8 L3 m) D8 {2 C; V
66 register ulong b = ntoh(k[1]); # }: ^0 w* R6 v5 ^6 d C
67 register ulong c = ntoh(k[2]);
+ a9 h* D" _- ^7 V- C6 u68 register ulong d = ntoh(k[3]);
) @& o7 c# O( E1 V69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 1 K- v( c Z, @# J& s
70 register int round = _round;
: ?: Q' Y! e9 R2 n& A/ x71 register ulong sum = 0;
- G3 W0 l' [# T1 Z+ @* S3 E72
; g `3 f7 R' v, F73 if (round == 32)
7 }* c( ^9 ^ Z74 sum = 0xC6EF3720; /* delta << 5*/
/ I1 l; A! J1 @! @75 else if (round == 16) 6 c+ q) R, K l% n7 |0 E
76 sum = 0xE3779B90; /* delta << 4*/ # e( p/ V' |2 R/ R& T2 A9 O/ U
77 else # |# p$ m1 `. _& I) v9 S0 \
78 sum = delta << static_cast<int>(logbase(2, round)); ; ^6 b, N! }3 U) d$ W; d* Z
79 : y i9 Z- ?& n
80 while (round--) { /* basic cycle start */
# c3 }, L1 C7 |81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); ; W' C6 b1 A3 X
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
A9 Z q/ X3 t6 @3 z. W1 u83 sum -= delta; / K3 k7 p" y. ]: r- _* G+ b# {
84 } /* end cycle */
' [& O) l; }) B' M8 D9 ^85 out[0] = ntoh(y);
! O/ x2 P7 ^( i4 u. p86 out[1] = ntoh(z);
! j, y* n5 K; t* q8 m87 }
+ s! F6 F9 E7 F$ X
6 g i9 o; `: r: N6 l5 x需要说明的是TEA的构造函数: % f, c4 p0 |. N+ D$ f
TEA(const byte *key, int round = 32, bool isNetByte = false);
. H( d: }: o! c- @" a- \1.key - 加密或解密用的128-bit(16byte)密钥。
. j( k4 C3 i" j' o. P9 w) e2.round - 加密或解密的轮数,常用的有64,32,16。
; N5 G! Z# F5 J+ g3 q+ H3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! 8 H9 ?/ k/ I& ]! ` P
: W3 f/ T+ m" ^: o: x6 \' Z最后当然少不了测试代码: |
|