|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" # B* d# I" F( y$ F* Z' r
2 #include <cstring> //for memcpy,memset
8 }- a; \) M. y 3 F5 @' j6 R k- n, {
4 using namespace std;
1 w- |6 G' Z, Z& i X 5
4 V" S2 p0 X4 a# i& X$ [4 l 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) 9 F$ Z. B( U. y
7 :_round(round)
6 }" H/ z- R8 ~! ~% X+ _ 8 ,_isNetByte(isNetByte) { ! s" T# l; c: @8 R) s+ w3 X( n
9 if (key != 0)
$ W' v# O7 A8 N# T10 memcpy(_key, key, 16); + `8 X( I, W6 N0 J' t0 b
11 else
0 a7 c" M0 h$ A: I' y) {: {% e: i# T12 memset(_key, 0, 16);
' B [' B4 q- } A/ _13 }
* o& y' K8 K9 E, D7 q14 V9 l7 n$ H) t2 L+ t5 R
15 TEA::TEA(const TEA &rhs)
) ?, o& }* t" R16 :_round(rhs._round)
- @ |+ g5 `% O1 F) `17 ,_isNetByte(rhs._isNetByte) { : P5 b! J* D3 D% {+ E: m) \
18 memcpy(_key, rhs._key, 16);
" X6 `/ \2 X! ]/ j19 } + Z9 m6 U- I: S
20 % N7 [+ I2 ?: l& O
21 TEA& TEA::operator=(const TEA &rhs) {
0 t2 F" J$ C4 b ?3 F1 @6 r' ]22 if (&rhs != this) { " I: [& d4 U) l9 o- z+ w
23 _round = rhs._round;
! O. e1 E( r7 D1 j3 E* D24 _isNetByte = rhs._isNetByte;
5 ~ b% J/ p: u6 k8 ~25 memcpy(_key, rhs._key, 16);
6 a# x' ]$ I$ U$ F. u8 R5 i9 D. i26 }
4 a% }9 f c" \27 return *this; G7 K- |: |& H) u9 ~
28 }
. T* L, ~, ^; b29
7 u3 E0 {4 P+ C30 void TEA::encrypt(const byte *in, byte *out) { 9 h. ~7 V2 u1 W! K# D- `- D
31 encrypt((const ulong*)in, (ulong*)out);
; X. {7 o; } f4 q+ N32 } $ ^( A1 E" M) S* r7 m3 c3 a5 D% l5 p! ` ^
33 : G6 D, x2 ]/ m4 P
34 void TEA::decrypt(const byte *in, byte *out) {
- G% [' i# I+ E7 A) D35 decrypt((const ulong*)in, (ulong*)out);
4 x! N( h- P* `- B. }36 } ) d8 Z/ O0 y* O, B8 o' Z9 t, n9 P
37 - r6 \6 B2 H& C' h* x
38 void TEA::encrypt(const ulong *in, ulong *out) { - s7 D# x/ o+ y5 r; J5 E4 }' Z
39
- q' q6 @( E5 ?1 C* `/ i. Y. T40 ulong *k = (ulong*)_key; 2 J! m4 f2 H* v1 n5 ^1 y! i/ \3 C
41 register ulong y = ntoh(in[0]); 9 b( U9 y" u4 X/ f+ p! I% B9 `/ s
42 register ulong z = ntoh(in[1]);
) U. |3 f: R: K: }43 register ulong a = ntoh(k[0]); : Z4 A, @( g3 ?8 I
44 register ulong b = ntoh(k[1]);
/ b, w5 N+ |& ^2 o% e* u0 [# \7 b" f45 register ulong c = ntoh(k[2]);
9 p0 Z! i! w/ }: E$ z" |46 register ulong d = ntoh(k[3]);
8 q" {1 E" X ]47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
9 B7 ~6 ?" X8 Q, X% a48 register int round = _round;
3 e5 {$ c& u% L; n49 register ulong sum = 0; 6 o; T* P7 a8 [1 }
50
8 L( G* r" M. l0 m% A51 while (round--) { /* basic cycle start */
5 b4 q: L5 g- F7 U0 C52 sum += delta;
' u6 ~2 S0 i$ g2 h53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); 0 F( O4 f1 W& p) ~
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); 4 N) H' a ?+ \4 N
55 } /* end cycle */
( C/ H! b1 `4 f [) p! S56 out[0] = ntoh(y);
/ j& I" n$ l+ R8 z57 out[1] = ntoh(z);
8 l5 s7 [- ]% c% i58 } 4 L) @6 {9 E" U3 X
59
' ^" j( V, b$ I- A! }60 void TEA::decrypt(const ulong *in, ulong *out) { 5 K! I6 s x& X# ~3 O, u \
61
: I A' m/ \$ U9 f1 f* h" l62 ulong *k = (ulong*)_key;
/ K9 C2 A3 Q+ Z: d1 U63 register ulong y = ntoh(in[0]); 4 ]8 O* L# w; f& \
64 register ulong z = ntoh(in[1]);
4 U. ~* o$ b' [4 \+ J65 register ulong a = ntoh(k[0]);
0 X( ^# B' a {! F: u8 i& V: S66 register ulong b = ntoh(k[1]);
! W$ `) ^: o0 Y. {67 register ulong c = ntoh(k[2]);
0 Y7 Q+ ]# V0 Q68 register ulong d = ntoh(k[3]); - t1 |4 |6 u \/ B( d8 ?
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ : i1 E* N' ^+ q
70 register int round = _round;
' R5 ?. X- C6 Z2 T9 B8 j71 register ulong sum = 0; 2 f1 ]& C( K* A, C0 V7 g
72
- V# a% t7 L8 \/ t73 if (round == 32) + T( y) N+ f6 [ w% H
74 sum = 0xC6EF3720; /* delta << 5*/
# A3 n' I6 \9 j9 U6 G75 else if (round == 16) ( r0 g$ R1 N: g" p
76 sum = 0xE3779B90; /* delta << 4*/ 5 A" V- A3 F5 B6 Q- A6 h
77 else 6 K3 n8 w7 ]' R% ?7 H X( X
78 sum = delta << static_cast<int>(logbase(2, round));
, a7 u: Y0 S" {- t2 ~/ I79
! b, @6 p1 |3 A2 b* U2 J80 while (round--) { /* basic cycle start */ - s! \7 u }2 y; h% M- B- r& u
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
# r7 J: j1 U0 Z; T! u" S5 U82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
6 V9 ?& M3 C# I0 Z; m83 sum -= delta; 8 |7 |* e9 Z6 s+ m
84 } /* end cycle */ . r* D4 C' f8 \2 t5 E4 s
85 out[0] = ntoh(y); 3 ]( D8 c3 c! U7 A! K8 X/ ~& i' a
86 out[1] = ntoh(z);
) }4 @* o' R7 k9 F87 }
' C& B2 s' b( N9 @% i
3 ]& X4 U9 b# B* E0 {需要说明的是TEA的构造函数:
) _! d( q, E2 z/ r7 GTEA(const byte *key, int round = 32, bool isNetByte = false); ] N/ a6 t' R
1.key - 加密或解密用的128-bit(16byte)密钥。 8 k& `" M9 }0 H
2.round - 加密或解密的轮数,常用的有64,32,16。
$ p! L! ~. f& S3 h3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! ! [' C/ @/ w2 t
/ Y) w" \. C% E" ^5 A" s' |; F; b最后当然少不了测试代码: |
|