|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
4 {" y& |( n: t# M& w; c; ^( i 2 #include <cstring> //for memcpy,memset " |- b4 o# ~) R* b
3 G) I, T1 O7 F7 U7 X5 c
4 using namespace std;
' L! R8 C" A2 B8 G: W% j% c 5
3 O* R& c/ L1 I' X 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) , `6 d) l1 T. H, C' S. R
7 :_round(round) * C$ B$ Z; h! ^7 G" C' O V+ ?1 _9 q9 _
8 ,_isNetByte(isNetByte) {
3 Y, ^+ g! F# n 9 if (key != 0) ) h# \3 B: a! `. N* }% b1 x
10 memcpy(_key, key, 16); : j. f f e3 n9 k0 D8 y
11 else ' z# r1 l' `) |- V& J3 v
12 memset(_key, 0, 16); 9 ~& g1 P+ G# P" X( Y' ?9 w
13 }
% W6 J0 U! K# c$ _0 d14 ; S6 R! Y0 ?$ @9 Z& s/ P
15 TEA::TEA(const TEA &rhs)
5 u( P- z+ x8 U/ O' w* y0 v8 @+ Z16 :_round(rhs._round) 8 c1 n& G& U) o% V- m9 S
17 ,_isNetByte(rhs._isNetByte) { ) h- W+ e% f: ?8 G& y$ c
18 memcpy(_key, rhs._key, 16); 8 n! \9 P8 X! A& E m
19 }
6 @$ I0 v+ W8 W# i20
, V3 O# P2 f/ n1 g) L. w$ W21 TEA& TEA::operator=(const TEA &rhs) {
4 r) Z5 t8 a. y0 }# s22 if (&rhs != this) { 5 r. d2 B6 ?6 V% j' H) a
23 _round = rhs._round;
- A) K- e" o% [1 D6 t24 _isNetByte = rhs._isNetByte;
+ d: K1 u" R y, Y7 E/ u6 u25 memcpy(_key, rhs._key, 16);
4 o& x# j& B: ~# [( @26 }
& c+ M" m1 y8 A0 w% A27 return *this;
' P! U. m: E9 T" M" F28 }
/ Y9 Y- U3 i( c1 _/ }, O) f* P29 5 D9 y- o' H0 N2 s
30 void TEA::encrypt(const byte *in, byte *out) {
8 S" J: m; p& W1 w. t) f31 encrypt((const ulong*)in, (ulong*)out);
/ s# k2 h# k9 x0 C9 K* H32 }
" J8 B2 w9 U3 G$ ^( m7 D( Z8 M33
) E% H+ h$ T2 I/ K: \34 void TEA::decrypt(const byte *in, byte *out) {
6 v5 x0 E: U% g8 B/ o35 decrypt((const ulong*)in, (ulong*)out);
7 Q7 D5 o. c0 a2 c8 @1 B36 } + |" U* G0 i4 F# t1 m8 {
37 2 u" w6 K! a8 F) [
38 void TEA::encrypt(const ulong *in, ulong *out) { & q4 l2 ~4 Q0 j# `& S/ Q, z& n' {# c! G
39
1 I' u! {, f7 T' }7 D4 s& m+ z40 ulong *k = (ulong*)_key;
6 [( c. w( B4 X% [! D41 register ulong y = ntoh(in[0]);
4 X* b6 Z/ J6 V# D2 f( K+ Y, J42 register ulong z = ntoh(in[1]); 1 x2 |! ^( v i6 o
43 register ulong a = ntoh(k[0]);
1 h" @' k) i# y44 register ulong b = ntoh(k[1]);
, r3 y- `0 I* q. l45 register ulong c = ntoh(k[2]);
, ^4 r+ z5 v) p; r4 F# }8 U6 j8 ~46 register ulong d = ntoh(k[3]); ' ^8 k( [/ ~. t" j7 E/ f
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
: k- q) `/ t/ x% G48 register int round = _round;
+ Z& w4 x) {; c; f; W0 N& I1 O, A1 K$ R49 register ulong sum = 0; + T7 w- j1 \2 I6 ^3 K7 N9 W
50 4 t: A( J/ L% s
51 while (round--) { /* basic cycle start */ ) h( _! X; M! G5 R9 H+ K9 m" F
52 sum += delta;
* K; B2 t" o+ D: Z53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
( {5 v) V' G: z3 _54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
0 D8 S4 v& @. s! v! N1 a( J55 } /* end cycle */ 8 J: J, B- o" ^# w3 e" b
56 out[0] = ntoh(y);
0 d; e1 Y% _" _ t) E4 A57 out[1] = ntoh(z); 0 f) s& Q& ?6 K: x6 B2 b
58 }
6 a( I% I9 G3 h+ I( M$ i( _59 4 g1 Y( Y# d3 a3 S2 X" K; T2 Y) l
60 void TEA::decrypt(const ulong *in, ulong *out) {
' `1 r4 b6 {; h7 J+ h, a% @61 $ d6 ?8 K5 A4 k1 p
62 ulong *k = (ulong*)_key;
8 Y) t3 `/ `; t1 [, ]8 ?63 register ulong y = ntoh(in[0]);
0 y) B& T* v J& K, R64 register ulong z = ntoh(in[1]);
& N z* ~8 }9 u4 K# d& [; d/ ~65 register ulong a = ntoh(k[0]);
& c" W; R9 {3 k+ r2 Q% Z2 c66 register ulong b = ntoh(k[1]);
B$ g+ T. ?7 w; j, m$ V+ x8 F67 register ulong c = ntoh(k[2]);
0 Z( V- J$ s" ]+ q9 J: X68 register ulong d = ntoh(k[3]);
8 I; m$ ]+ @: s$ w" S69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 2 o; O [8 V' `0 l* X
70 register int round = _round; 1 L# C( _5 Z# H$ A$ h* b
71 register ulong sum = 0; 3 O1 t5 k; {. m. B$ Y6 p+ b7 h
72 " z" H% M. [: p
73 if (round == 32) ! b& `, g; W% |: [, S
74 sum = 0xC6EF3720; /* delta << 5*/
; W0 H- B; ^5 h" g& H5 W75 else if (round == 16)
: W1 G( r9 D: c0 H! p* x9 K76 sum = 0xE3779B90; /* delta << 4*/ 2 i( E) `. q( M% ?: s( Q; R
77 else , y' Q& {* q* l
78 sum = delta << static_cast<int>(logbase(2, round)); L) y% q1 h" y; X) D* U
79 / f) k5 D# z5 @! ?2 y
80 while (round--) { /* basic cycle start */
3 `# D- g+ c5 M, h+ x81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); 6 \. X- g* R( e& Y
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); 5 P o. B8 k8 q! M2 f
83 sum -= delta; : i7 v+ p6 w4 G' |! x+ S
84 } /* end cycle */
/ H1 C2 @- A* _. k, I$ h E* t: R85 out[0] = ntoh(y);
$ _ J! S) y" V S" y86 out[1] = ntoh(z); , m0 @. Z2 [$ Y. t! n
87 }- ^8 C6 |, ~- D* I+ K9 y) L' x/ x
5 ^5 r* _; a3 @" E# y需要说明的是TEA的构造函数:
% V- q$ l* Q! j! p; {( B) [* UTEA(const byte *key, int round = 32, bool isNetByte = false); & h( h( C4 A0 m$ o
1.key - 加密或解密用的128-bit(16byte)密钥。 : n& B* Q0 | l' B+ g' |, o
2.round - 加密或解密的轮数,常用的有64,32,16。
9 A; r; M* n7 t( Q( B3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! $ p. [8 q* o" l0 t/ Z, L5 t
3 b1 x% [( |- c
最后当然少不了测试代码: |
|