|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" [$ K- A' }6 I: Y1 p: k
2 #include <cstring> //for memcpy,memset
$ J1 H9 ?$ c. x6 i% u* _/ v 3
: W9 ?7 I5 x* D8 ~! n 4 using namespace std;
, ]# i2 O; x8 p9 _+ x- m0 t 5
$ q* R# r% N B4 _; x& c$ X4 J& t6 | 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) * ]7 S# W Z9 { h2 ?
7 :_round(round) " M& z# D9 H3 x) o1 o9 G) f
8 ,_isNetByte(isNetByte) {
( e4 u. C& M, F& S$ F1 p 9 if (key != 0) $ p: F6 [ S5 s3 M2 N3 Q
10 memcpy(_key, key, 16); @ \8 G+ ^) V5 A/ @# x
11 else
$ m4 d! }* s- s+ A: k12 memset(_key, 0, 16); 7 r7 A0 s: \+ v' ?- j1 f
13 } $ W. h3 K" F3 b# C- Z Q( |
14 % f6 U1 D& F3 j% E5 f* D, S
15 TEA::TEA(const TEA &rhs)
# J. J I5 l6 F( ]2 A+ k16 :_round(rhs._round) % I: n3 p+ j% i
17 ,_isNetByte(rhs._isNetByte) { 2 H/ Q5 ]( k# `+ d/ ]9 I% J
18 memcpy(_key, rhs._key, 16); 3 v' {4 g% x& s. d: x4 f
19 } 6 t. Q% B( T* j1 r
20
1 z- |0 e* n3 m7 z' l" p21 TEA& TEA::operator=(const TEA &rhs) { , `" B# h; J& j
22 if (&rhs != this) {
a- ~* U' C* f1 r2 |23 _round = rhs._round;
5 I9 k/ D" J2 X. {$ s- v7 c6 W0 q( w24 _isNetByte = rhs._isNetByte; , y+ c k3 T: b/ e% W
25 memcpy(_key, rhs._key, 16); 5 B& A1 u2 c% F) M2 E
26 }
; C7 k, ]% X: _- h/ v( ?27 return *this;
3 j; a( H& M% q$ W6 L28 }
P9 I8 \- V' s5 g29 % E# F0 h% g! x Z8 [$ x7 [; H) c$ W( {
30 void TEA::encrypt(const byte *in, byte *out) { 9 _$ k$ B! b. X& s5 x" A
31 encrypt((const ulong*)in, (ulong*)out);
5 p I+ c8 R: P% `2 C& ^# i. H! n32 } 5 a4 n, r/ }. W$ D' m! s* ` k& e
33 2 y1 w8 t/ ^7 @
34 void TEA::decrypt(const byte *in, byte *out) { , M, T2 B7 E4 Q5 X6 Z" ]
35 decrypt((const ulong*)in, (ulong*)out);
- Y8 b% O( s3 B9 T) b6 k$ p36 }
# P9 U t) w0 X Z) b; C! z! {37
p4 w+ Q1 J5 m9 l3 @- h7 s- ?$ [38 void TEA::encrypt(const ulong *in, ulong *out) { $ B. ^- I/ n1 J8 L6 o4 a
39 - K1 F! `7 b" k7 m/ f' }
40 ulong *k = (ulong*)_key;
& n$ M7 F0 m k; q! _. D* f41 register ulong y = ntoh(in[0]); & T8 I6 j; \' {0 l$ l! Z8 J9 L
42 register ulong z = ntoh(in[1]);
0 f1 _, {) d5 z43 register ulong a = ntoh(k[0]); % o) ~# A& o$ s2 I* E
44 register ulong b = ntoh(k[1]);
" N8 T) C5 B1 o( z9 @' i45 register ulong c = ntoh(k[2]); 7 }, c( i# y, r- |; Z' F) {2 z. u
46 register ulong d = ntoh(k[3]); & ?( a% n* E8 g0 i; G; j. d9 T
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
, E% t2 k$ X- b1 Z1 W48 register int round = _round;
% Y! H' F+ d- p5 R2 @4 x6 u, P49 register ulong sum = 0;
$ h4 m9 L0 J' {7 T4 Y( S50
( \/ B5 v! J8 r) x- g6 n51 while (round--) { /* basic cycle start */
3 |1 L; k2 p+ `9 N1 l" w52 sum += delta;
6 {) ~. [/ \/ U' Q( \53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); # t% }4 [: M, Y: U3 t
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
, g: F) N$ Q+ [' Y' g5 u55 } /* end cycle */ 4 n$ j' n z; q! i) N
56 out[0] = ntoh(y);
, {' G! v. C& U& ?% E) N57 out[1] = ntoh(z);
- i# y. b5 d- d; X& Q) h58 }
/ g9 \: z7 t3 q1 L59
, A' F) J7 [1 w7 ^% b2 w0 O6 X) i60 void TEA::decrypt(const ulong *in, ulong *out) {
" L ]; g7 s2 ~1 n* P61 $ b6 t' H6 i- e3 X/ @- c' M m: U* h
62 ulong *k = (ulong*)_key;
7 v+ x8 c3 D: {( K) |63 register ulong y = ntoh(in[0]);
/ j5 D" b) X2 ?, l# a7 j4 L64 register ulong z = ntoh(in[1]); $ J! H" x! Q" _ `( ^
65 register ulong a = ntoh(k[0]);
! p( f7 \' Y0 O" d# Q: P u* N7 _66 register ulong b = ntoh(k[1]); / K: Q v( Z @) E; \5 s
67 register ulong c = ntoh(k[2]);
( w# @$ |% U8 ?) J; ]68 register ulong d = ntoh(k[3]); 7 c( b, X5 n. P8 d% x ^
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 1 W; X4 j: ?9 E) r! A6 m( W. D
70 register int round = _round;
2 ^4 l' B, Y8 |' r$ Y, ?9 R71 register ulong sum = 0;
+ j; z6 c, K* X! `& K9 A72 ! U1 n3 p8 h9 z* S
73 if (round == 32)
- Z. Q7 k! r% U+ m74 sum = 0xC6EF3720; /* delta << 5*/ + q( k- r. z( L, v1 ]' x& N0 G% g, a
75 else if (round == 16) ! h# ?1 k0 `- y+ r+ ?: V, r! J
76 sum = 0xE3779B90; /* delta << 4*/
" D3 q* R" a$ C6 j; K5 s! n! _) P77 else
) U7 w4 f# Y ?# A: F5 a3 v78 sum = delta << static_cast<int>(logbase(2, round));
9 p% p0 c$ r# c4 N2 j f. N. Y79
% X* D. r' w. p& ~80 while (round--) { /* basic cycle start */ 3 |5 ~( B2 Q+ v" x% H0 L- j
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); 8 v7 x6 P% o/ R
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
( M$ a; T. t" ^6 c& s83 sum -= delta;
$ \; U5 C$ e# d84 } /* end cycle */
& u" t: J( I O2 ?) _ _85 out[0] = ntoh(y); % r, j# r7 j) E/ I
86 out[1] = ntoh(z);
. R# `$ N- G5 C+ D$ ~87 }
' m. `( L# F' |4 N( G( Q7 e6 M" \ G
需要说明的是TEA的构造函数: & z. Q; p5 T+ j) @# a" @% B6 E! M, A8 J
TEA(const byte *key, int round = 32, bool isNetByte = false); * d3 V! q7 p. B5 W$ p( p' c
1.key - 加密或解密用的128-bit(16byte)密钥。 + j9 t. u; A5 S$ n, y9 A, H: h" W0 J
2.round - 加密或解密的轮数,常用的有64,32,16。
7 k0 p# D9 W% N4 B8 h( ~3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
5 ]2 e4 r |3 H; G! T
! S( B4 }. P; _6 O9 U! Y. `最后当然少不了测试代码: |
|