|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" & t- Q2 m* s! t! q# a- T2 r8 n1 E/ ^
2 #include <cstring> //for memcpy,memset
, |+ H% V6 s9 X2 J4 U 3
1 z4 k1 F* S8 K 4 using namespace std; " G7 n& V" Z( @4 I. \1 h6 e
5
1 j6 a" x* L0 ^" b. m 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
8 C8 K4 `* X2 W/ S" i) x 7 :_round(round) ) b% F) m. b( y" k" a
8 ,_isNetByte(isNetByte) {
0 C: T- M; I& Z7 d) ? 9 if (key != 0) 0 n* z. F( _+ |4 b7 z- @7 |) I
10 memcpy(_key, key, 16);
& H1 {/ A/ u8 O$ Z+ l11 else 7 r! z7 d$ c0 I! S/ l
12 memset(_key, 0, 16);
% b- Q" n- {0 T; H+ D% h" [13 } 5 z* Y* {6 v+ s8 @' I; [
14
7 P" E7 `! X. a+ |15 TEA::TEA(const TEA &rhs) $ x( A' I, D* W) h2 S
16 :_round(rhs._round) % T. j. k: X i9 _, Q. p
17 ,_isNetByte(rhs._isNetByte) { 8 m/ ^+ \+ `) {* J
18 memcpy(_key, rhs._key, 16);
$ w$ u4 J4 Y+ k0 M0 }2 V19 } F7 G1 Q( Q* ?
20
, B, L0 z+ F4 Q4 c21 TEA& TEA::operator=(const TEA &rhs) { ) H$ }" c' M/ {% o5 }# b
22 if (&rhs != this) { 3 {. ?9 B2 J$ Z& j
23 _round = rhs._round;
% g* q4 o5 X6 Y6 p$ S24 _isNetByte = rhs._isNetByte;
1 ^1 L6 y, _. e% b3 q. L6 t/ [/ K25 memcpy(_key, rhs._key, 16); % d' B A3 g1 k. X1 v1 D
26 }
: O; S8 B- C: x8 B: v; h27 return *this; ; @: o. F, l/ i3 \7 |% V) n# E
28 } * V M3 F" T, s. d; h7 V4 q! _
29 ( n: Z9 _) V8 T9 F j; A
30 void TEA::encrypt(const byte *in, byte *out) { + D, c# j- \) s& k) r; q
31 encrypt((const ulong*)in, (ulong*)out); 7 V1 p& w1 E" {' G) U" w, R! B' U
32 } 0 m" B& B4 g( a# ~/ j
33
' Z2 ?& K- D, W6 x7 i. a34 void TEA::decrypt(const byte *in, byte *out) { - Y# p' z- u3 q R7 u& B0 b5 b
35 decrypt((const ulong*)in, (ulong*)out); . L( U- A/ I- M/ `
36 }
' Q6 e! v4 g! D& b$ E( F37 8 V" H, u4 \3 ~/ z8 K d9 `
38 void TEA::encrypt(const ulong *in, ulong *out) {
9 S. {- y j8 `# N! F! K1 S39
7 |8 J& Z/ E t! {( s( h; e" W40 ulong *k = (ulong*)_key; . h& q6 k+ L) R# K
41 register ulong y = ntoh(in[0]); 7 G9 f; Q* ?, i! Y% V. H
42 register ulong z = ntoh(in[1]); 0 z$ z5 [0 E7 j- x3 D
43 register ulong a = ntoh(k[0]); ; C9 O* c/ j3 ^$ _1 E+ T
44 register ulong b = ntoh(k[1]);
5 W/ g- R) P6 A* I" L45 register ulong c = ntoh(k[2]); 5 h3 Z" o0 o. V7 R
46 register ulong d = ntoh(k[3]); + A% A4 Y$ J- X# k% ?
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
+ h; i1 N. H" f# ?1 n9 b48 register int round = _round; 8 {( G8 l0 P. y, `9 |& L% m: A
49 register ulong sum = 0; ( e/ ]8 C1 ?) g0 L0 ]. C
50
# |+ [5 {, D9 O- ?' z51 while (round--) { /* basic cycle start */
7 v) @: {/ V8 [3 _% l52 sum += delta;
- B" {& h& ~9 y- F53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
! n, J1 a/ q _54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); : k& n( v( c1 w5 q
55 } /* end cycle */
2 X/ X. } \% l/ d# X56 out[0] = ntoh(y);
( {, d3 N# ~+ g6 @" p57 out[1] = ntoh(z);
* T* q6 X$ F& `% T3 {* L: L. r; k58 }
* B' a, H* {' b J59 3 K' x" q) V3 ]+ }& f2 r3 R) d) B9 z
60 void TEA::decrypt(const ulong *in, ulong *out) { % o" U: A) M) L' |. s# ~4 p
61 6 s& \3 r- d7 \- b7 V& h& {
62 ulong *k = (ulong*)_key;
, k$ F4 o& |3 O7 w3 M4 L0 O8 o63 register ulong y = ntoh(in[0]); * y0 K( ]2 n+ P X
64 register ulong z = ntoh(in[1]);
# o/ r% m0 I z; c, B7 L5 V65 register ulong a = ntoh(k[0]);
& n4 Z1 }4 A5 l1 m9 Z5 Z; D66 register ulong b = ntoh(k[1]);
: I' x- n5 l p. |; }67 register ulong c = ntoh(k[2]);
5 j4 w% j1 H8 q, R1 e. e68 register ulong d = ntoh(k[3]); 7 ]7 [ A4 f1 `6 c7 l
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ " q8 h1 N% l. _
70 register int round = _round; ; N9 y( O3 h7 {: b1 Z2 u s
71 register ulong sum = 0; ! j, x0 l) s: E2 q' s2 _
72 # T) m$ D& e, W
73 if (round == 32) 7 x. Y9 [! K% r* e* ^9 N) C% j% r& I
74 sum = 0xC6EF3720; /* delta << 5*/ 4 E- M0 @4 Z# k
75 else if (round == 16) # A. b* m8 w' t3 f
76 sum = 0xE3779B90; /* delta << 4*/
$ ~. o0 ?; ^3 y+ B( l- B& B77 else
# n Y$ \2 e) a$ N/ K3 ^78 sum = delta << static_cast<int>(logbase(2, round)); % L) j# s! o# _9 F. j7 M- T
79 ( l9 D+ M) e6 Y! n
80 while (round--) { /* basic cycle start */
* d! _& z5 e* {) X/ P" ^81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); # x/ `1 Y$ U" \$ M6 [% Y+ `+ v2 v8 W
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
7 d2 C2 R. P+ s% ^' ]$ N83 sum -= delta;
" t3 X5 B3 n# A84 } /* end cycle */
* D: Z4 ^4 Q8 _+ m) E85 out[0] = ntoh(y); 5 Z( V0 G1 u& L+ r
86 out[1] = ntoh(z); 8 H( u, t& ` l1 Z- R- w
87 }3 F& c( E& |3 j1 n2 m$ b( l/ x& P
. T; _% U- X, T1 j; U, D- X4 a
需要说明的是TEA的构造函数: 7 m V: W4 ^; J" L5 e
TEA(const byte *key, int round = 32, bool isNetByte = false); - r4 i6 u) O" f3 C1 z
1.key - 加密或解密用的128-bit(16byte)密钥。 1 @+ X5 n* O5 W( M; F
2.round - 加密或解密的轮数,常用的有64,32,16。
4 `) |% T7 {$ X9 K x3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
+ g8 \) O0 q: B, k8 c. E& w( v! \4 I0 G! b* t
最后当然少不了测试代码: |
|