|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" d6 V7 ?0 ^5 B" `9 W
2 #include <cstring> //for memcpy,memset 4 Q% x5 u- M6 E; v5 M
3
( K# H2 I7 I: a 4 using namespace std;
7 V: a& i* I- i 5
4 H/ H4 h, w7 X/ F$ g9 A& d3 M5 A 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
8 k3 W! O9 F7 z 7 :_round(round)
: c8 A: q0 O8 a4 G- Q+ \ 8 ,_isNetByte(isNetByte) { ( t9 H# Q# g" w+ r! W! C
9 if (key != 0) 7 o$ C b0 E: S3 r: M) f; E" F% i7 f
10 memcpy(_key, key, 16);
9 v0 _& _: ^: J8 |3 Y$ x. f11 else
& Z" V0 L* ^; n3 ^8 h& r# N( F12 memset(_key, 0, 16); 3 X$ s, f% C8 h7 Q7 k0 I
13 } % J$ m$ ~( Y/ f/ N4 r
14
, Q9 ]4 \6 p4 o6 E15 TEA::TEA(const TEA &rhs)
( G4 X" s0 w1 Y9 V16 :_round(rhs._round) % R* ]; p% H& V
17 ,_isNetByte(rhs._isNetByte) {
, g: M1 d x M7 I. F2 N18 memcpy(_key, rhs._key, 16);
6 r2 M) |( z: Z6 U/ A19 }
7 l2 h6 E* ^$ h3 W20
. {) w: S1 x c2 x7 e8 i8 \21 TEA& TEA::operator=(const TEA &rhs) { * ^ Y0 ~, f/ m6 j: \5 V
22 if (&rhs != this) { $ H5 o/ S: D( L) M$ u
23 _round = rhs._round; - i( I" o; v- m
24 _isNetByte = rhs._isNetByte;
) i* z1 |' E' u6 w4 _' _9 }+ d G25 memcpy(_key, rhs._key, 16); / L; e0 x! y1 T/ P7 @( W) Z9 {0 x
26 } 3 A+ {% U4 ?/ g7 o; ^0 _! t
27 return *this;
|8 D3 H2 J& N3 |28 } " f; P: P# `! @% Z
29 ) }" Y: U0 s2 o8 A& c
30 void TEA::encrypt(const byte *in, byte *out) {
3 t) E8 L* v n! d5 k) B9 A31 encrypt((const ulong*)in, (ulong*)out);
& c' X j2 j* S32 } . b* U- ?! {# |: Z$ i
33 ; r5 v- k; }5 V8 f( Q
34 void TEA::decrypt(const byte *in, byte *out) { / Y* ]5 @% H5 A3 ?3 `' B* M2 G( c! O
35 decrypt((const ulong*)in, (ulong*)out); % y F( {* e. J. ` Y
36 }
, E8 W! D4 b% \% d5 J; V8 t# N37 ; g" }+ [! o$ \2 ?5 q) @
38 void TEA::encrypt(const ulong *in, ulong *out) {
0 _0 H: q1 `7 E5 O3 T39
! o0 [" n! m: O40 ulong *k = (ulong*)_key;
9 G9 Y! p) o7 _0 u2 b41 register ulong y = ntoh(in[0]);
3 B4 x, V$ Q6 E" K8 h42 register ulong z = ntoh(in[1]); ) A8 a$ d } t( b% {! o
43 register ulong a = ntoh(k[0]);
( U7 b! t7 w7 s6 S44 register ulong b = ntoh(k[1]); + q2 l X r( f! d5 s7 L5 w+ }
45 register ulong c = ntoh(k[2]); " Y! X3 z! O7 ?) a; [( ?
46 register ulong d = ntoh(k[3]);
! d! e8 {# Y! k# \47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ * v" X: G1 U% S& ?9 E' l. S& K0 b
48 register int round = _round; 9 U& _* j" p' M& x! x
49 register ulong sum = 0;
; U! }1 L' [, Y' v50
, ]/ j2 }! X/ C8 T+ x, c4 x51 while (round--) { /* basic cycle start */
5 X' f% V; s0 X. B, U0 I3 O+ R52 sum += delta;
. ?7 g& k6 T0 _% W: w53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
v4 b: V( {/ Z7 a. z$ x54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
, e- a# F3 N6 m1 Z55 } /* end cycle */
8 k6 v& H- L5 ~. U56 out[0] = ntoh(y); + b/ _4 K% Z* b) U. E
57 out[1] = ntoh(z); , m" _/ U( v) |6 E
58 } * S. Y1 Z- H `' t
59 . ]* B9 v* c* e) x
60 void TEA::decrypt(const ulong *in, ulong *out) {
5 r8 @# { p* k, L* b9 T, p8 C61 7 v/ x8 O* l) O v. e
62 ulong *k = (ulong*)_key; 0 o% F S( X. a
63 register ulong y = ntoh(in[0]);
1 G1 m8 x- U% F/ o+ P' c- o64 register ulong z = ntoh(in[1]);
) `. g8 k5 j! g1 @65 register ulong a = ntoh(k[0]); 8 F" s( B% e( A7 I7 S* c \
66 register ulong b = ntoh(k[1]); 1 d) ]/ j$ R/ w" J% A' k, Q, [6 T; {
67 register ulong c = ntoh(k[2]); 1 T: X' J; |( h K) L' E
68 register ulong d = ntoh(k[3]);
/ a. j2 [3 {" Q: y# E$ r( h69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
l4 F5 O) d' Q, s1 W) E7 \% |70 register int round = _round;
: \, V# L. w$ s* ~71 register ulong sum = 0; 8 u! m/ J O5 Z
72
( ?+ h/ Y; w* @" x; l9 R73 if (round == 32) 0 t" T/ |+ a6 V1 I" P
74 sum = 0xC6EF3720; /* delta << 5*/ 3 u. Q l" X( R" Y
75 else if (round == 16)
& i! ~5 k: I+ v( I! E+ N" j76 sum = 0xE3779B90; /* delta << 4*/
- `. w2 A- P# u$ {; `5 @77 else
. W& F6 X) s' k o78 sum = delta << static_cast<int>(logbase(2, round)); $ Z. T4 L1 H4 J" @
79
1 m' P G; f' n; x1 m' {3 v80 while (round--) { /* basic cycle start */
* {$ H- Q8 f7 Y% c6 Z% t81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
, }, |) B# B% U82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
" ~6 F. p6 j4 |83 sum -= delta;
, a# D. W, d0 a2 W u+ n! P& g84 } /* end cycle */ & p: z3 Z) {% g% E
85 out[0] = ntoh(y); 3 s1 M5 P0 ?, M' ~3 F" N2 [
86 out[1] = ntoh(z);
2 S" H+ R% m3 G. i. V) u8 {87 }
. }# ~$ m1 p9 v7 _9 ?% h2 W6 T* j: g( ]
需要说明的是TEA的构造函数:
% v6 Z# f4 M' MTEA(const byte *key, int round = 32, bool isNetByte = false); 4 E# f3 S1 C/ o: I, V- q" Q* x% k" e1 I
1.key - 加密或解密用的128-bit(16byte)密钥。 % g4 R9 v$ z, i2 Q; K2 w" F
2.round - 加密或解密的轮数,常用的有64,32,16。 ! j+ a0 f/ K* M5 t; l" ]2 [% D
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! 4 |' o" @4 X: {+ }/ g
$ @* Q! f, I1 y& O& [最后当然少不了测试代码: |
|