|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
& M% W1 N( s3 W$ e( }- i1 p' f 2 #include <cstring> //for memcpy,memset ( x8 Z3 D4 P5 n0 W
3
) q4 o1 |% Y/ n- n4 G( T! U% U 4 using namespace std;
- ~/ Y+ |: g0 \6 l% `, ] 5
6 B) y8 P9 m5 ^" V/ ?# o/ } 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
, Y) N& [& [" ?, [/ `5 `# y 7 :_round(round)
0 S! u2 ]$ \! c1 q- s 8 ,_isNetByte(isNetByte) { 4 ?" p( K$ i$ [/ _# o
9 if (key != 0)
* |7 F$ i3 f y% U) ?: h% j10 memcpy(_key, key, 16);
' i" i9 N+ {7 C11 else 7 b) |# R% a) s
12 memset(_key, 0, 16);
# v9 ?! [$ B7 g( F" `13 } ( L) `( h$ V6 _# J
14 9 ?2 M, M: y v: J. @
15 TEA::TEA(const TEA &rhs)
% \$ a2 n) B# p( E$ i16 :_round(rhs._round)
0 J5 w8 \+ ?5 G7 E; u17 ,_isNetByte(rhs._isNetByte) {
: |1 D1 D: R1 D6 \4 j5 v+ s18 memcpy(_key, rhs._key, 16); 5 s$ x2 L9 _; K$ ? L+ p1 j; @ ?
19 }
2 ]1 O1 i6 K$ C) n; N20
8 _( ?& _4 G4 Y# R" x# b21 TEA& TEA::operator=(const TEA &rhs) {
7 b. t1 w [6 ?7 S- f22 if (&rhs != this) { / f7 ]/ I V+ [+ L
23 _round = rhs._round;
; Z* G ~9 C& C9 p24 _isNetByte = rhs._isNetByte; / ]3 ]: D$ m+ q4 [1 N9 d
25 memcpy(_key, rhs._key, 16);
. ^9 D' }# t3 g" W26 }
# n+ S* E8 K2 U27 return *this; # j& N0 k. C/ G$ ^1 i
28 } & ]3 S' E* B, L6 v9 Y9 E) j
29
0 G* i- G* R0 o9 t1 d; `30 void TEA::encrypt(const byte *in, byte *out) { + p8 O" |2 K8 {+ ?" e
31 encrypt((const ulong*)in, (ulong*)out);
7 F3 v/ _* l5 A% P32 }
0 t' X4 i% D: u* C33 7 B, I7 L1 v8 Q, R5 i$ f+ i
34 void TEA::decrypt(const byte *in, byte *out) {
, D& z4 P5 H/ n8 m$ l35 decrypt((const ulong*)in, (ulong*)out); # |) y+ n! S9 i$ Y) i3 l3 j; q# ~
36 } 2 C; F* L8 k! |
37 8 m. Q# Z; |8 ~4 F
38 void TEA::encrypt(const ulong *in, ulong *out) { + |3 W+ h5 K: ~- m
39 9 z1 G% d3 ^) }" }& [
40 ulong *k = (ulong*)_key; - H e+ N% e8 K) ?
41 register ulong y = ntoh(in[0]); 9 r& b3 j- H2 S# G+ C o) c
42 register ulong z = ntoh(in[1]); ' H, r9 t) b4 o% M2 Q. g$ f; r; |
43 register ulong a = ntoh(k[0]); 3 O) x, z) t( y
44 register ulong b = ntoh(k[1]);
( F0 O# k! a5 @. t45 register ulong c = ntoh(k[2]); 9 c$ N) B9 d, ?( y b: ]
46 register ulong d = ntoh(k[3]); ' o2 f" q0 A5 H# n: X9 A
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
2 O1 H0 ?' G$ E0 d G- j& ]48 register int round = _round; # H8 `7 K U" z
49 register ulong sum = 0;
: z( C. `" `" G50
5 ]/ `; t ~/ s4 D51 while (round--) { /* basic cycle start */
2 c1 J( \) j, p1 d6 t3 k52 sum += delta; ) W# }2 n$ j4 Y( K9 g" K5 `
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); ( u* m: T( r3 c' a1 L
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); " c# H8 T0 I0 ^& Y
55 } /* end cycle */
- i5 h9 e% v4 R56 out[0] = ntoh(y);
, R+ }2 F ?6 T7 E2 }57 out[1] = ntoh(z); / z" y% X9 P9 d, K, |2 C. b2 k" R
58 } 5 P0 D( n$ ]9 m+ h6 T
59
+ D. h/ C% c5 U# Q, V0 f$ L60 void TEA::decrypt(const ulong *in, ulong *out) {
/ E- M" U8 ~0 S: e3 D5 s" H d61
7 K5 W; r3 @; w% W( [+ e' C: P62 ulong *k = (ulong*)_key; % I1 s( P1 x$ K
63 register ulong y = ntoh(in[0]);
, O. J9 M4 k/ i6 _% R' }2 G7 f64 register ulong z = ntoh(in[1]);
' \, H& a' [& h c; f. p65 register ulong a = ntoh(k[0]); 0 \7 s+ _3 B' ~* X% A+ L! N) q
66 register ulong b = ntoh(k[1]);
6 J+ _% p( t* L$ d67 register ulong c = ntoh(k[2]); 1 F7 n/ `% i% k4 X, `
68 register ulong d = ntoh(k[3]); u6 u& k7 a0 E. Z
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
# O9 q! V. |$ W# j: @' N A; ?70 register int round = _round; 9 [/ n% k' e/ f2 b' M3 z
71 register ulong sum = 0;
% u$ m5 @0 Q+ s# ?" c- }, Q72 4 n2 b- k3 V1 F2 r
73 if (round == 32)
8 S7 I1 [) _+ \0 p6 Y74 sum = 0xC6EF3720; /* delta << 5*/
" g+ R" U1 [7 L0 D8 p0 z: i2 c75 else if (round == 16)
6 |" j1 U1 j+ F! [+ o" N( @" Y76 sum = 0xE3779B90; /* delta << 4*/
. R4 W* F" @) B8 ^) y# X- a77 else 4 H" R# g! q/ {/ ^9 C! ^/ G
78 sum = delta << static_cast<int>(logbase(2, round));
0 ^4 [3 o7 e" ?. N5 Y6 y2 r* O79 ' `( x3 L0 L; z, m2 Y& ?9 M
80 while (round--) { /* basic cycle start */ 2 L) K& J! m0 E& j, ~
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
" g+ t4 N! X: P( W# k82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); 4 }- @; S3 g8 I
83 sum -= delta;
2 V/ ]4 U* A: ~% [0 ~84 } /* end cycle */ : \1 U% f( ?7 n
85 out[0] = ntoh(y); }! e- L# m4 E( _: z
86 out[1] = ntoh(z);
1 Y4 c7 S- m6 Y6 X) m3 C% ?" A87 }( u. B/ c% y$ [8 ^
3 f& m/ h: G' I
需要说明的是TEA的构造函数: 9 L3 \8 P7 u& t, M. S
TEA(const byte *key, int round = 32, bool isNetByte = false);
- Q/ x& I9 \$ X6 g1.key - 加密或解密用的128-bit(16byte)密钥。 3 ?& \% ^, V3 I
2.round - 加密或解密的轮数,常用的有64,32,16。
. E) A6 o$ S$ L6 o0 Z/ b3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! 8 M9 o l8 I! b( X" f h
/ I# p5 [: v& H' _* M* d2 {
最后当然少不了测试代码: |
|