|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
, N; ], l( R" K. n4 o6 p 2 #include <cstring> //for memcpy,memset ! G, ^" x5 V6 q, K! L( B
3
7 G" ~- O& I1 R- n 4 using namespace std;
5 {) V$ j) E; K/ t, x 5
: C5 Q6 i+ P7 ~% N) G3 A2 k 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) # s4 P. q/ ]5 l2 w! \7 ?- G
7 :_round(round) 5 q+ l* D8 m/ y# z
8 ,_isNetByte(isNetByte) {
0 \- A) U( L" K( S" a 9 if (key != 0) 9 J6 N K& u- Z4 |
10 memcpy(_key, key, 16);
; M* N# h* X3 d4 a1 m' Y11 else
( D8 ?8 H5 \/ z) _12 memset(_key, 0, 16); 8 F$ @- V& w* {5 \8 T+ P. o
13 }
) F* Q! B- j R' m+ n14 - M' r1 j) l2 ]# M
15 TEA::TEA(const TEA &rhs)
. P, @2 p4 E/ @" T3 r16 :_round(rhs._round) . V( @0 x+ n$ A2 C6 [7 \. A! `
17 ,_isNetByte(rhs._isNetByte) {
- ]( E6 g% S7 F# T18 memcpy(_key, rhs._key, 16); - G6 W" z/ ^; d
19 } # k. ~9 }& l6 Q/ s, O P
20 & y2 i$ {3 f" c. `$ g4 T/ M0 j4 F
21 TEA& TEA::operator=(const TEA &rhs) { * o/ r% J1 I7 Q1 e" p) B
22 if (&rhs != this) { & d( V7 w# T- v ^' r% ~8 c
23 _round = rhs._round;
5 q, H& B. E8 n$ q1 |, r2 t# y& B24 _isNetByte = rhs._isNetByte; . Q5 p/ q/ ]% X) i7 \
25 memcpy(_key, rhs._key, 16); $ S+ \; r. \" m1 L5 {
26 }
c/ K3 |% F+ m8 X* @7 h2 |( n$ ?: ^2 B27 return *this;
3 s# `! @: a3 Y8 K& H$ ?28 } 9 c- G* |$ J* @% i- y
29
- r2 l$ i$ r2 q$ z1 l6 f) v30 void TEA::encrypt(const byte *in, byte *out) {
+ @- h7 p# B$ K* z4 K$ a6 A31 encrypt((const ulong*)in, (ulong*)out); 1 s: Y3 w: n6 O) y2 `! a3 k+ S |4 z
32 }
- ?2 L2 S( a& g( r/ N* X33
8 f2 |# e5 G- A9 ^, ~34 void TEA::decrypt(const byte *in, byte *out) { . v, w" p! Z4 ~' }
35 decrypt((const ulong*)in, (ulong*)out);
+ ~. e; h1 J$ I- A- F. s' h- Z36 } " P9 P$ U; e, E
37
4 m/ I7 k0 s* ^" z2 r7 Y3 w4 L38 void TEA::encrypt(const ulong *in, ulong *out) {
9 ~ I: U- P/ d4 K R5 e% F39
/ k9 F- A+ w, M8 R/ u# j40 ulong *k = (ulong*)_key;
# t* @/ d$ h+ _3 @9 O2 r9 H41 register ulong y = ntoh(in[0]);
8 q" ?" Y* r. R7 q! n; r2 A42 register ulong z = ntoh(in[1]);
8 c$ m' r" t$ }6 `" M43 register ulong a = ntoh(k[0]); ( z' m$ Y& K& w: a7 r5 D# B1 R
44 register ulong b = ntoh(k[1]); / y+ p% }/ b8 B2 u
45 register ulong c = ntoh(k[2]);
1 o. Z. F7 d; m" U46 register ulong d = ntoh(k[3]);
# U \7 g y4 w9 d1 N9 e" C. H: s47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ ' b8 x3 L% b% m k8 j# c4 I
48 register int round = _round; 6 q7 }5 \! g) Y0 ^; V7 Q# h8 O4 A
49 register ulong sum = 0;
/ [' G: s) }. E& V( W50 + s2 A* E( `, L- R4 W+ `. H
51 while (round--) { /* basic cycle start */
+ G0 ]. O; ~. R& B$ M9 U52 sum += delta; 0 D0 ~7 O% x' ~' |3 a6 B
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); * h" ~& i N: x3 ]8 h! d; h6 W
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); " p- W8 p+ o% ^2 b/ h4 p
55 } /* end cycle */
0 P1 ?3 f2 \- r8 G8 l0 I- \% g& u56 out[0] = ntoh(y);
: d) ]' Z f3 ^/ N, z3 W57 out[1] = ntoh(z); ; k8 G- d+ E+ Y- [0 G& r9 {; }0 Z
58 } 3 F3 j; `# m# z/ e2 H* c. W1 J
59 / j- J) H0 l. W; l( v
60 void TEA::decrypt(const ulong *in, ulong *out) { , z$ c4 i5 X' s
61
F" z& R. S6 t9 f0 f62 ulong *k = (ulong*)_key;
5 Q3 T( B: l2 u! U, J4 K63 register ulong y = ntoh(in[0]);
! K5 t: |7 \1 u2 f% m: R64 register ulong z = ntoh(in[1]);
) _4 W$ C2 O6 l65 register ulong a = ntoh(k[0]);
6 r0 T& t3 @9 @" g- n66 register ulong b = ntoh(k[1]);
7 y8 h' U8 {5 d, B+ b1 V/ n67 register ulong c = ntoh(k[2]);
) W5 i/ w3 w: ^2 t6 ]68 register ulong d = ntoh(k[3]); + r9 H# m5 W1 [7 r/ A
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ : ]* G `+ ^6 d, ?% ?
70 register int round = _round; $ w o8 @8 v c: T* E4 s0 g8 h
71 register ulong sum = 0;
4 ]7 L7 F- [) |- E6 c72
) o/ c; |: { T O73 if (round == 32)
1 R+ m" {2 W& {7 M74 sum = 0xC6EF3720; /* delta << 5*/ . J) ^0 p# b, p T
75 else if (round == 16)
6 |: q) ~- E: Z% ?# f) K" f! x2 W% v76 sum = 0xE3779B90; /* delta << 4*/ 9 N. u+ Z: `+ j: ~ M& ^( ?
77 else , z3 G1 q) B' E, o3 v' F
78 sum = delta << static_cast<int>(logbase(2, round));
. H$ s- r- B" c" ?5 K79
" `- c9 M+ a/ ]9 u0 q) K1 t) D80 while (round--) { /* basic cycle start */ $ ?6 I/ c' P! `0 T; q& d
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); , X- b8 X; U( J* m( A9 `
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
% n9 v% `% {" Z) q2 j83 sum -= delta; / }1 \3 F5 E% `
84 } /* end cycle */ ( X: R$ e; n) b! G
85 out[0] = ntoh(y); ) @7 t" x3 \$ E, R2 A. G* G
86 out[1] = ntoh(z);
- s$ n! x3 V' l( a, |& N* ~& ^87 }
" ^ \) e' y5 k3 O V0 D( \( w/ U, f
2 H* ^, s) _( O9 G需要说明的是TEA的构造函数:
9 a; U( |# t0 t7 Y2 I! ?TEA(const byte *key, int round = 32, bool isNetByte = false); & _* z$ q& \! ^8 q, V
1.key - 加密或解密用的128-bit(16byte)密钥。 / T: i" }1 \) h& {! t7 S
2.round - 加密或解密的轮数,常用的有64,32,16。
% ^; |3 F8 `' k) s. [( E$ h3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! ' M* O9 P: h# W% F
/ o- Y' U T* c4 ^
最后当然少不了测试代码: |
|