|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
0 w5 W: P3 s3 N& k; ^9 P, ? 2 #include <cstring> //for memcpy,memset - U7 A( K! y2 U0 w; F
3 " M: }5 s: v6 \; `. i8 N, L' K; R
4 using namespace std; ! ^1 l6 I- E# X8 f8 o0 F" @! J" { {
5 + z0 ]' i) l. M2 \" H2 o
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) 2 ^! O! O- A+ J5 `! q
7 :_round(round) : J m, n6 h: W' K# W
8 ,_isNetByte(isNetByte) { ) j* z, J/ |2 t# V
9 if (key != 0) ) `4 A& f( k) b- [% {
10 memcpy(_key, key, 16);
2 _. P1 p0 |6 L11 else
) I4 A' Q6 j$ {. N' ^12 memset(_key, 0, 16);
8 N+ m" [+ U2 F) Z2 j O( M13 } 5 h N3 K! ^9 B7 L
14 ; }2 Q6 {/ L/ s. d$ F
15 TEA::TEA(const TEA &rhs) ; E. g( ~/ X' N7 O. Z
16 :_round(rhs._round) - _" J' t& x; D4 c( _% |) t; X# {
17 ,_isNetByte(rhs._isNetByte) { * s0 N ^: ?# ^ ?, g9 ?; C+ L
18 memcpy(_key, rhs._key, 16);
$ ^/ e8 r/ j! A+ d4 x7 R5 e) w& Z# f19 }
! U" s, p, d! o3 ]9 L1 D4 D20
8 ^; x: q9 [! ~1 a21 TEA& TEA::operator=(const TEA &rhs) {
I% }# m* q: }4 I' ?3 f22 if (&rhs != this) {
. @* B8 b9 R# e2 n, M$ L23 _round = rhs._round; % s3 Q0 X' V& r( E# a
24 _isNetByte = rhs._isNetByte;
! P' T$ j5 I* q' t2 }25 memcpy(_key, rhs._key, 16);
) c) f% A0 Z9 K$ _7 D% X26 }
9 m# X) h+ _( g& D1 |27 return *this;
8 f. s; `: r M0 @( h" b! y; E28 }
9 p- R, |6 _! Z. i+ T6 f29 ; [: v7 r* p6 i9 D
30 void TEA::encrypt(const byte *in, byte *out) { 4 n6 w- ~, K8 D/ c5 u
31 encrypt((const ulong*)in, (ulong*)out); : I: ~) z! `) M/ y X/ A
32 }
3 m6 |9 ]3 @% o1 [33
6 d5 F9 Y- P9 s3 N, Q1 N, A34 void TEA::decrypt(const byte *in, byte *out) {
! K& e& C% B# {* t' n35 decrypt((const ulong*)in, (ulong*)out); 7 {; {% m' _' S% h% y3 A& G
36 }
9 g. S8 h( H4 d2 N q& U- y/ H7 j37
$ g6 J2 V4 X! x) N5 `2 M38 void TEA::encrypt(const ulong *in, ulong *out) {
5 Q4 x7 W$ s9 D+ H39
; s" o/ s A# z3 e8 f- m7 S40 ulong *k = (ulong*)_key;
; G+ F+ X8 [( L4 }& S$ S8 D p5 q1 H2 J41 register ulong y = ntoh(in[0]); . u+ u3 T' x5 ]- Y2 _
42 register ulong z = ntoh(in[1]); O: s. k& @6 X; s* M8 g) v
43 register ulong a = ntoh(k[0]); 6 g3 I8 H9 C3 C; ]2 |
44 register ulong b = ntoh(k[1]);
" V5 h; a3 W1 r! _& e7 K% b45 register ulong c = ntoh(k[2]); 9 L9 ]6 N# W& M. J4 N
46 register ulong d = ntoh(k[3]);
, n6 m+ D2 m: |2 j+ j4 L+ Q47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
. X- S, g/ {5 v1 l$ X, v! E48 register int round = _round; 4 [9 k0 A3 \7 D& u- ^) E8 c
49 register ulong sum = 0;
0 J: w8 J# p7 [50 5 b2 |7 Z/ b4 ~- f- `
51 while (round--) { /* basic cycle start */
* t) ~9 S% T I; a" M1 J6 j52 sum += delta;
1 P+ a& c/ }4 k, |53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
) W ]8 I# L, u" ^9 m; Y54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
o8 c2 `2 ^# R# e- ]: r0 c55 } /* end cycle */
" B' [5 o$ R* o56 out[0] = ntoh(y);
: o( {9 ]+ E% G! z3 i# p$ r57 out[1] = ntoh(z); 9 }- L8 ^) x9 x- c6 u
58 }
: S2 i* \& i4 ^" L0 m4 e2 K59
; a8 o; K7 c/ q' v( P6 S60 void TEA::decrypt(const ulong *in, ulong *out) {
5 {, |7 w" m9 v2 _61
, L' m+ _. ^" p W9 R, [62 ulong *k = (ulong*)_key; ' T* ]' o* Y; c' d* }' V P. L3 {
63 register ulong y = ntoh(in[0]);
1 l8 U! {6 K( L( _ A64 register ulong z = ntoh(in[1]); 3 [9 H) }: Y0 q5 U) p2 E
65 register ulong a = ntoh(k[0]);
8 M" f+ p; A+ j: ` o8 Y66 register ulong b = ntoh(k[1]);
4 u, f4 e$ H* V, c8 ~& N' O# O67 register ulong c = ntoh(k[2]);
6 V, S& h8 o2 d8 c68 register ulong d = ntoh(k[3]);
% K& S6 [& g) |+ o69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ $ _2 G, t$ Z0 g D
70 register int round = _round; & y, }" w! m" U; f
71 register ulong sum = 0;
( V: T G& c( ?7 n/ |72 % S7 I$ f2 n, Z$ H0 F. p4 u
73 if (round == 32) . N2 v. ? U5 S3 k3 f1 L$ K- I
74 sum = 0xC6EF3720; /* delta << 5*/
) {$ {( t9 H, e6 [75 else if (round == 16)
3 t" v( R! f3 F8 c2 z' X& U& {76 sum = 0xE3779B90; /* delta << 4*/
0 s; m+ H3 O: C3 c3 B; J9 R5 q77 else ) k, v5 c e' U* o0 |4 K5 i0 O. G
78 sum = delta << static_cast<int>(logbase(2, round));
* l4 d" h- [! l' k4 s, x, x$ i79
/ u8 W# f3 X, D T, b( Z80 while (round--) { /* basic cycle start */
& m4 c1 E9 \8 F {81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
7 w! b9 m5 J9 B/ E- ?) n8 w9 q82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); ' p6 B! V5 s! U8 w+ j6 P; B
83 sum -= delta; # f5 w6 L% @1 O* ~( p7 Z0 O
84 } /* end cycle */ ) B h2 G' d% H7 i
85 out[0] = ntoh(y); 6 i4 f; O- L$ k7 q
86 out[1] = ntoh(z);
' r2 [9 Q' n) C) W S) s4 R0 G* n/ X" z87 }1 n: [3 E1 ~7 o) Z; F/ ^. D$ }
; R3 M: H, y& @4 z2 u4 k# a: }
需要说明的是TEA的构造函数:
" Q3 r4 i' u$ u& C" CTEA(const byte *key, int round = 32, bool isNetByte = false); " ~) }+ t5 q; B) E. G! f" P" c: L
1.key - 加密或解密用的128-bit(16byte)密钥。 - N1 R: C# X( ?# k" A; t* B( y
2.round - 加密或解密的轮数,常用的有64,32,16。 $ H' x! P2 F( {5 t1 X2 c
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
* d0 }5 f9 {% t; U- t1 c: ~* Z& s9 N( U2 I$ M( K, \" b/ j( w6 l' `
最后当然少不了测试代码: |
|