|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" ' o' @0 L( \4 R1 {9 }! X' w
2 #include <cstring> //for memcpy,memset
/ j8 O" {4 z+ |# W2 I& e0 f: } 3
: N1 ?0 K* A! \ 4 using namespace std;
$ K9 r; G7 [% g& \ H' A 5 ! r5 [! h4 F' b4 s
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
4 Z; H) L3 ~% L# @$ \ w 7 :_round(round)
; T$ ~- |$ @( l 8 ,_isNetByte(isNetByte) { 6 Q0 {9 @, O" y( L1 q
9 if (key != 0) 5 S# P9 [% h( c! T: P4 |+ R
10 memcpy(_key, key, 16); ' N' L# h6 K' h& ^8 P
11 else
+ G+ j/ X! W7 i( j& [, U12 memset(_key, 0, 16); / k+ v" \$ X, p# b* a
13 }
1 V2 Y, h! g( n0 J2 z4 s14
, Z, ^$ {( r2 P/ _, s15 TEA::TEA(const TEA &rhs)
/ i' Z& W! A. O3 I) }16 :_round(rhs._round) # K& H; l0 {9 \6 r2 r; s$ N& D
17 ,_isNetByte(rhs._isNetByte) { ; n" D) a* Z* @. d$ v" [2 C: J4 p0 w; P
18 memcpy(_key, rhs._key, 16); 4 V1 z0 E: q3 \0 H
19 }
" M+ ~2 y8 |3 V# n$ _20
" r& a) i Z+ f- v21 TEA& TEA::operator=(const TEA &rhs) {
% C+ \# F+ N8 u6 g, r1 P22 if (&rhs != this) {
y' w( p% |+ [) S! K# d/ ]( r1 y23 _round = rhs._round;
# p, M& @4 [: O t: X$ A24 _isNetByte = rhs._isNetByte;
3 e- j5 n$ ^8 d( \! L! B9 X% [2 f25 memcpy(_key, rhs._key, 16);
y; B0 {; [( x26 } 2 S" Y- y* e, B$ W7 V1 {& z
27 return *this; ! n ]9 M: L7 l1 M% h a
28 } ; T2 b- n7 ~# M
29
3 @6 {% D7 y8 f8 s5 E5 N30 void TEA::encrypt(const byte *in, byte *out) {
& N# A" o5 t8 q+ M7 \+ H5 V! g31 encrypt((const ulong*)in, (ulong*)out); + p5 s( ^. l; o% W; J1 k3 X+ n
32 } 5 L2 d/ A. ]8 M/ E3 Y- Q4 l
33
& N ?& x# ?' w3 B" R% W5 D2 v8 k34 void TEA::decrypt(const byte *in, byte *out) { ) i* j# i! H+ B/ M u+ f
35 decrypt((const ulong*)in, (ulong*)out); + J1 H0 A# y% _: r* e* S" Q
36 }
/ I) X9 T$ C a6 G+ I37 1 F; }# F2 ]0 U3 ?) a7 O
38 void TEA::encrypt(const ulong *in, ulong *out) { ' c& G) J8 a0 m4 X/ X# ^
39
, j0 o- H' H4 K6 A, ?40 ulong *k = (ulong*)_key;
. K/ L3 [1 @' a2 b4 i) K# \- I+ w41 register ulong y = ntoh(in[0]); 5 L) {1 h5 M7 K \4 C
42 register ulong z = ntoh(in[1]);
+ q1 r! ?% S1 A# d3 C& ]9 ?43 register ulong a = ntoh(k[0]);
4 K0 x+ Y/ ^6 a! B( q4 ^; l2 \, c% ^44 register ulong b = ntoh(k[1]); + F4 l( ~% a* ~( n
45 register ulong c = ntoh(k[2]);
$ L6 r) g, k* `1 F& C3 o! |46 register ulong d = ntoh(k[3]); ) ^7 u. _: P/ ]3 d9 z
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ ; _& j# ]9 |2 t& w/ P' J+ e
48 register int round = _round; 5 r5 [2 J& c6 w1 F
49 register ulong sum = 0; 0 I: P. k+ O0 A$ [
50 ' V; g) i0 s; g- _9 w
51 while (round--) { /* basic cycle start */
$ a% y3 P! C; A: m9 A! I4 q7 B52 sum += delta; # j& S# B0 I6 i) Y$ v# `
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
+ j R* ]9 u% P54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
% c% h( N3 |7 T1 s! j9 J55 } /* end cycle */
, ?: f+ ]3 @3 U# p( }6 T+ L56 out[0] = ntoh(y); - h* m8 I9 F. L/ a5 \9 B. T
57 out[1] = ntoh(z);
' s/ E9 P+ C5 U) o. K/ @9 g58 } : a4 B2 M3 o! m; q4 x. t8 W, R, N
59
& p7 N2 ~% A: J0 Y- v: Z! O60 void TEA::decrypt(const ulong *in, ulong *out) {
" M8 G U' D0 X1 |' b61
1 ]; T, M. ^" o( D# F62 ulong *k = (ulong*)_key; # S: ~+ M: I) E3 p( S
63 register ulong y = ntoh(in[0]); 0 Y- }# j5 _$ `! q; s2 i. |
64 register ulong z = ntoh(in[1]); % |7 A) O2 s8 W3 b
65 register ulong a = ntoh(k[0]);
8 w$ y: P& N; V5 b) m66 register ulong b = ntoh(k[1]); : f- b& R( Y l+ ~; u
67 register ulong c = ntoh(k[2]); 2 f! Z0 k6 k) x. d# q. l* E
68 register ulong d = ntoh(k[3]); , t$ |& z! n6 F4 g
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
?$ }8 ]& e0 E# b% A70 register int round = _round;
5 |# w5 L( m$ ?7 n5 M8 Z1 g71 register ulong sum = 0;
6 y: q: _2 W8 t& J& l72 & }! v6 x; {3 Z7 \. q2 ^
73 if (round == 32) 4 ]& [' _9 t6 j/ i: u6 W
74 sum = 0xC6EF3720; /* delta << 5*/ 1 m1 Z* o' O/ ]2 @# [
75 else if (round == 16)
I" B+ n0 q |: l8 @8 M! r' N d76 sum = 0xE3779B90; /* delta << 4*/ + j4 R' s$ u7 l
77 else 6 o7 m% h w# K
78 sum = delta << static_cast<int>(logbase(2, round));
7 i3 T7 G! a2 [. L79
5 m: t4 n b6 s80 while (round--) { /* basic cycle start */
" l7 b J& O! x' k4 Y5 T81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); + |3 g1 _3 `( }8 a6 a- I
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
3 C ^# ? s6 P& b9 `1 z83 sum -= delta;
. D5 ~2 W) o) M( F0 W1 N9 y84 } /* end cycle */ % m3 T# b8 l) v7 k4 b9 ^4 i
85 out[0] = ntoh(y); * f( w9 r8 V$ u8 S; ~9 }: l
86 out[1] = ntoh(z);
( y# z Z D8 m6 @ g7 l87 }
+ C6 c7 D* B, I% B4 s
, y: X, g9 x$ _ }& T1 m需要说明的是TEA的构造函数:
# z5 p/ r6 P; {1 P! E- K, ]TEA(const byte *key, int round = 32, bool isNetByte = false); $ Z0 S. a! L. C* \8 w1 M
1.key - 加密或解密用的128-bit(16byte)密钥。
7 x4 [0 n7 h* i# {% n( b5 v7 y2.round - 加密或解密的轮数,常用的有64,32,16。 : B9 D5 @+ C% u8 ?. n
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! " L7 T. a$ {# J$ b
5 |. p7 d2 |; L) X
最后当然少不了测试代码: |
|