|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
8 C" V, H/ \1 q [8 w+ ?2 M" u/ h 2 #include <cstring> //for memcpy,memset
1 j: a- E. e, K* o& J 3 0 {1 m# ]# z- `: R+ i
4 using namespace std; / S/ O3 z0 w/ O6 d) B* f/ U) ?
5 " r8 t, p- |- ?
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
9 x4 L' T5 V4 u: O0 H _6 D 7 :_round(round)
: f) w0 d, d+ [. ^ 8 ,_isNetByte(isNetByte) { % J; r2 P+ d9 `5 h
9 if (key != 0)
( N$ b( F: R* q+ w10 memcpy(_key, key, 16); ) Z# d" y" p9 t4 |7 ? D M# v
11 else # a- P: u+ S. \
12 memset(_key, 0, 16);
# e9 ]$ k! v7 o$ ^* i' `13 } - X: C4 t, G6 N8 }: P
14
1 A3 r8 p/ u R- O2 }3 l( t. ]5 p( c15 TEA::TEA(const TEA &rhs) 6 ?( j/ X3 A- D; B( B9 L; @" R
16 :_round(rhs._round)
0 g+ {. l, C$ H; F17 ,_isNetByte(rhs._isNetByte) { 2 V* b% B/ _" v' J
18 memcpy(_key, rhs._key, 16); * V2 R1 L- Z: N) n2 d0 R+ F
19 }
& `' \: j, ^4 x* k i6 i3 w20
5 q# m2 C0 u# W# E21 TEA& TEA::operator=(const TEA &rhs) { 9 w- d( X% n. |& t; n/ i
22 if (&rhs != this) { 7 Z8 N! z: Y( A" r% C
23 _round = rhs._round; ; R3 ?' j/ U6 a4 a% X1 l1 i
24 _isNetByte = rhs._isNetByte;
- B+ [, k, j' P5 k4 J$ c25 memcpy(_key, rhs._key, 16);
n+ G; m% P* ^26 } ' _) V$ F" g1 T1 ?% L9 z6 x( s
27 return *this;
* G% q! M% p* ~! w28 }
$ g1 b; ^* ~" \; t" {29 8 o" b& @7 v7 p- A
30 void TEA::encrypt(const byte *in, byte *out) {
; U: }$ b- Z3 X4 x31 encrypt((const ulong*)in, (ulong*)out);
9 Q4 V5 {) l% ~1 x32 }
/ ?" B5 N, P+ |' L( U- H33 ~3 c9 d* Q$ r2 | @
34 void TEA::decrypt(const byte *in, byte *out) {
! v% y3 c( I& E4 m; M/ P1 ^35 decrypt((const ulong*)in, (ulong*)out); 9 v1 `- v9 b$ l7 c3 F1 C
36 }
) {& w3 A0 b% r# q% F5 _6 }1 x9 x5 X37
) n# M# B: f; A3 N- V38 void TEA::encrypt(const ulong *in, ulong *out) {
, H! |9 x" Q+ ^/ ^6 h- Y39
1 v) t. E, L/ t, Y40 ulong *k = (ulong*)_key;
) D' T" x$ v* w2 y; g1 q41 register ulong y = ntoh(in[0]); " h# _: W1 p" X+ H8 V
42 register ulong z = ntoh(in[1]);
% t; y C3 Z- u0 g2 L. J43 register ulong a = ntoh(k[0]); 4 M4 y+ u' m- P" k6 H( f
44 register ulong b = ntoh(k[1]);
' R$ f2 [1 W1 g" K45 register ulong c = ntoh(k[2]); # g; ^; `) o, b5 @9 X2 T
46 register ulong d = ntoh(k[3]); # A* Z2 k/ S$ A& T
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
6 d: C0 u" \9 H& w) h48 register int round = _round;
0 n5 e, @' V0 P; }4 t) h% n49 register ulong sum = 0;
5 V1 P: C" J& H' J# o50 " p) z! z3 E5 N! O$ j
51 while (round--) { /* basic cycle start */ ' }" G( h& b8 P' Z# m1 a# u
52 sum += delta;
2 G$ z, ^/ A' p) m53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); m0 c7 q" a. K U; j" P; D
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
3 K8 d7 d) o: o7 c4 ~* e) I55 } /* end cycle */ 7 c& h8 a$ C+ M7 C, b
56 out[0] = ntoh(y);
^2 O) r+ k5 W$ W: x" o7 A. J57 out[1] = ntoh(z); # i( z# [1 h/ v; e
58 }
: s6 \7 b# S) e- M" }! L) J3 V3 R59
$ w3 c. y2 V! a" I3 X! q/ e! N Y60 void TEA::decrypt(const ulong *in, ulong *out) {
' s% x4 e y, i6 Y61 1 M2 N" K5 ~. ]; h _6 M# w
62 ulong *k = (ulong*)_key;
% c- d! b% y8 U! Q6 l63 register ulong y = ntoh(in[0]);
# V. P7 D6 [* P5 V4 Y' u64 register ulong z = ntoh(in[1]);
" J$ {) K6 j# B65 register ulong a = ntoh(k[0]);
% T: S+ Q6 b4 O9 Y w66 register ulong b = ntoh(k[1]); 8 D5 b3 P3 v2 w" \$ r9 s& g3 ]' R% n
67 register ulong c = ntoh(k[2]); ( m- F+ H- \" y% o, {7 s' [
68 register ulong d = ntoh(k[3]); 6 q3 x% l9 O1 k3 [
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
b; \. J9 k/ e9 W- ?6 k70 register int round = _round;
! b; J# o/ z- _, W71 register ulong sum = 0; 9 ^" g2 a( B1 _' \7 d; U$ d
72
/ ~" U8 ]3 }5 l5 {3 }5 \" R6 O1 |73 if (round == 32)
' o- L% x& i' ?# b, F8 s74 sum = 0xC6EF3720; /* delta << 5*/ 0 x( u, ~* p6 Y" @1 L/ k4 [! D( l
75 else if (round == 16) 4 z0 n! p; v. \
76 sum = 0xE3779B90; /* delta << 4*/ " @# p" o( k3 E
77 else
4 [* X" \7 }( l' u$ j78 sum = delta << static_cast<int>(logbase(2, round)); ' i/ B0 Q( a* ?% K1 `' K$ ^ e) S
79
. G& g/ R! V) h/ L) L; E! f* ?80 while (round--) { /* basic cycle start */
1 b; X% t$ C$ P/ W$ }+ U81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); 1 e2 R, j! e/ ~1 s& ?# A; D. c
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); 1 O) b1 @( {1 K
83 sum -= delta; " t* R( c0 n3 m1 p6 [
84 } /* end cycle */ - H& {# Q- E# S: v8 z
85 out[0] = ntoh(y); ' L% t- V3 O! E/ A$ }3 g# p
86 out[1] = ntoh(z);
. X0 D+ t z" O: b: s4 w87 }& q R9 Y( z! j# e
8 B; Q6 h- l O, P' t! @* ]$ o
需要说明的是TEA的构造函数: 1 S' u0 e3 G9 N; p
TEA(const byte *key, int round = 32, bool isNetByte = false); ) \# l" ~ E) ], P0 {" a5 M
1.key - 加密或解密用的128-bit(16byte)密钥。
) s2 K9 N. k3 N! C h2.round - 加密或解密的轮数,常用的有64,32,16。
* B1 U' |" M+ j; @/ }4 _3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! 4 s5 n- e9 }$ W/ t4 ]
9 u/ R, H f5 J* |# k$ V' E3 \最后当然少不了测试代码: |
|