|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" 3 p0 r* W. f, d4 Z5 |
2 #include <cstring> //for memcpy,memset 8 T+ U0 \/ }; Q2 ~8 I
3
" u* a3 D' V) ~, T 4 using namespace std;
0 W" E" @( Q/ l- S7 c, M$ v5 \ 5
3 Q: ^1 C5 V: e5 T& Q' s, v8 j 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
' v8 Z$ o) ~$ y2 J. f 7 :_round(round) % W& a2 K& \ [/ B: K6 f( K* `+ ~
8 ,_isNetByte(isNetByte) {
" r) i2 v7 d1 z, J( R7 p 9 if (key != 0) ( i6 ]$ b! a% o/ ~ N
10 memcpy(_key, key, 16); ; X- D) F/ j C% X( z) v. t
11 else
, U; s# v' y3 y# T8 f) F% C& g12 memset(_key, 0, 16); + {2 u2 V+ H: }+ v
13 }
2 W' N' _1 h! Z! d14
8 {' Q- {! n9 d15 TEA::TEA(const TEA &rhs)
9 I3 H: a' u; w2 q7 h, p$ P, P16 :_round(rhs._round) , Y* @$ ]" A/ |
17 ,_isNetByte(rhs._isNetByte) {
, ]5 o( B( t/ X: }- K# V18 memcpy(_key, rhs._key, 16); , d( Z+ j1 |+ R" ]- W
19 }
0 }9 E4 v1 u4 k5 w5 X5 s20
4 C2 Y' L% K" Z7 `8 i+ X21 TEA& TEA::operator=(const TEA &rhs) { ! m" p: z3 L" `
22 if (&rhs != this) { & s' x$ I- D8 q5 f) K& }
23 _round = rhs._round;
: G& x) w: R. V( R; `, q24 _isNetByte = rhs._isNetByte; 3 [+ }* X) S2 {7 L
25 memcpy(_key, rhs._key, 16); 3 M7 ~+ h5 [/ y$ J, V
26 }
0 B/ D. `! e1 T5 Y8 C1 R) a4 K1 r; i27 return *this;
- l" N p# Z! @" G) Z+ W28 }
5 ~. F9 n' k L0 k } }29
6 s; R. X3 o3 s6 f% P; B7 t30 void TEA::encrypt(const byte *in, byte *out) {
$ z- G- ]/ B# {3 l31 encrypt((const ulong*)in, (ulong*)out);
' V! j4 y* ]- W4 }5 i32 }
' r. x, z: i4 [/ Q& ^33 5 F* ^$ O* l' v6 n7 s2 e6 l
34 void TEA::decrypt(const byte *in, byte *out) { $ z0 S3 V2 g( c& w" [
35 decrypt((const ulong*)in, (ulong*)out);
4 }0 |% i' `) X: r, A36 } 8 G6 P0 m. h' e0 L9 p4 v
37 ) \( a$ T8 `; P( u7 a
38 void TEA::encrypt(const ulong *in, ulong *out) {
% T+ F0 ]9 k1 o. ^/ ^8 h9 w: @3 d39 : A" V: H) T( ^4 r2 V% `4 R
40 ulong *k = (ulong*)_key;
+ K2 m3 P! C/ w0 i41 register ulong y = ntoh(in[0]);
0 R. h7 A1 ~* F; X42 register ulong z = ntoh(in[1]);
" W) \; \! T9 A( p43 register ulong a = ntoh(k[0]);
" M8 X/ @+ `* D. e44 register ulong b = ntoh(k[1]);
2 r# j6 o6 T* f/ X$ q45 register ulong c = ntoh(k[2]);
O& |( g1 B, n2 o6 A46 register ulong d = ntoh(k[3]); 9 Z$ s v! j2 M F( x
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
4 s4 o# `7 B) d) }9 B48 register int round = _round; 7 }( V" B$ A1 d% d1 z
49 register ulong sum = 0; + K% B$ H' s- E+ @' [8 V
50
1 E$ t9 N8 X+ ~9 S* ?& }! C0 ^; \51 while (round--) { /* basic cycle start */ . L- Z7 ^# B" f M' n" b
52 sum += delta; ( Z5 L$ L& v5 S6 ^& C; P/ h
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); " F! j$ j: e' Z) U9 ^$ W k
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); . W/ e: y( D# R' r/ s
55 } /* end cycle */ 0 g8 s/ H8 }9 |' i7 a7 o2 H
56 out[0] = ntoh(y); 6 x- }. n0 [3 O4 K
57 out[1] = ntoh(z); 3 U* Y& E( ^* H
58 } 4 b; K) a9 O- Y+ Q; D: z
59 % v9 x5 z/ O$ U/ ~% I4 n
60 void TEA::decrypt(const ulong *in, ulong *out) {
$ m$ P5 H1 G4 q- B' f# F* t. [61
' P$ u) O: ^; b1 T' B8 A5 k62 ulong *k = (ulong*)_key; : @$ H8 ?; b7 B+ f. [4 B$ \# [/ l
63 register ulong y = ntoh(in[0]);
5 j# r! j2 L. D1 q9 a$ ^# {64 register ulong z = ntoh(in[1]);
4 I! W7 T q" }' I4 j65 register ulong a = ntoh(k[0]);
9 o) m- d; R2 j! Q66 register ulong b = ntoh(k[1]);
; u# z# | F: I; ]0 S67 register ulong c = ntoh(k[2]); $ v4 q3 V$ {1 j5 n7 m
68 register ulong d = ntoh(k[3]);
O# Q* R" M8 I+ E# o& X: E69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ - N6 t3 S* N% S7 d& Z5 _& t( N
70 register int round = _round;
e; l$ W+ C: L% {4 X71 register ulong sum = 0; % u! ~: S0 n, p
72
% W2 V7 I7 ~: t! S) _2 ~73 if (round == 32) 1 o, X( p3 c$ a! u3 Z# A3 x2 G. w
74 sum = 0xC6EF3720; /* delta << 5*/ # P2 A) L3 e5 q# Y+ r9 Z
75 else if (round == 16)
) X! m/ q* Q+ p2 E76 sum = 0xE3779B90; /* delta << 4*/
5 P7 R+ u0 o \- F77 else
- e' w0 s1 r7 R$ n78 sum = delta << static_cast<int>(logbase(2, round)); 8 A, ]4 U$ E& ^2 l/ s0 `+ Y
79 - O/ x, B' z& l& [8 h- U
80 while (round--) { /* basic cycle start */ 8 h( [: ?+ I( F
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); ) F# |" L" e4 a u
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
4 j; T2 ~* F2 B- e83 sum -= delta; # z" V+ E# B3 T2 D: z! R0 M A4 D- w4 l
84 } /* end cycle */
. |0 ~& \5 m9 R0 t85 out[0] = ntoh(y);
6 x; W7 ? r6 Q86 out[1] = ntoh(z); # f) a, n: q9 r* m! ~7 d
87 }
8 ?2 a/ C) G/ F: |
, |# P7 Y5 _/ T p需要说明的是TEA的构造函数: d! r p. ?. A9 o8 u E. j. S# x" M
TEA(const byte *key, int round = 32, bool isNetByte = false);
1 a4 d1 l0 R2 M1.key - 加密或解密用的128-bit(16byte)密钥。 ; W5 w% T- a' I2 U, w) w
2.round - 加密或解密的轮数,常用的有64,32,16。 9 U& J) { W% h, ~8 k! ?9 s
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
1 l) ?4 h. [1 ~& \* o* L/ m9 ^. d( R( Q6 H( s
最后当然少不了测试代码: |
|