|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
8 O' S2 b9 C9 H8 N6 m D3 I6 d$ W 2 #include <cstring> //for memcpy,memset
, o- L# O" n2 M g# x 3
3 j o! E, G e 4 using namespace std;
- `9 U$ g C+ F8 ` 5 8 p/ b/ M' w1 ^
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) , X% F/ `1 R1 T2 t) z8 Z7 k2 n
7 :_round(round)
" ?, h: C1 ^1 {- [) `& d 8 ,_isNetByte(isNetByte) {
' D4 W8 M, C+ ^7 Y* R- W% J) ~5 { 9 if (key != 0) ) ^) ]: N# s- s" D3 G3 V# m+ u
10 memcpy(_key, key, 16); % p! N9 z' V% K8 s# E. q( a
11 else
1 M6 x; S1 ~2 A8 Z2 S# q* I" ?12 memset(_key, 0, 16); 0 q, z9 `! R0 L1 F
13 } . w0 e- F& b) J1 V
14 & V- }" P2 R* i( K1 `/ j
15 TEA::TEA(const TEA &rhs)
4 ]9 v! E; d4 U; X16 :_round(rhs._round)
, @4 y! Z7 e; m2 G* q2 R17 ,_isNetByte(rhs._isNetByte) { ( t6 S1 l- c4 q, V3 z
18 memcpy(_key, rhs._key, 16);
$ X3 z% J: E$ W2 |/ ]2 P$ q3 M19 } 6 Z, g5 H! ` L$ F* i# ~# E; F6 {
20
1 |9 _, `9 c- b6 _& p: b7 ~21 TEA& TEA::operator=(const TEA &rhs) {
: a4 G8 w/ B8 I* \ C+ z22 if (&rhs != this) { / ?# q8 g4 |6 M: s. R# m
23 _round = rhs._round; ) }( W+ t: G1 b4 d: G% }7 L
24 _isNetByte = rhs._isNetByte; # K# b, r7 U! b8 g/ I" x
25 memcpy(_key, rhs._key, 16); " \$ X0 L3 g+ u
26 }
" Y5 u. H$ L4 P# Z3 h27 return *this; 4 g/ u+ P" J% n9 N# |7 h4 |6 d
28 }
. U" n2 B/ j6 q29
* {( U9 Q/ M2 H8 h6 B0 d30 void TEA::encrypt(const byte *in, byte *out) { * u" T- W3 Y; I; t' |4 `( S6 f
31 encrypt((const ulong*)in, (ulong*)out); _3 X( e; P; P3 I" E
32 } 7 h' |0 G; r8 m3 J* y# l
33 ! ]( A0 y! z. p3 h) @
34 void TEA::decrypt(const byte *in, byte *out) { " P) |$ Y5 G5 d: ^- y5 E1 K
35 decrypt((const ulong*)in, (ulong*)out);
* ]- }8 e+ v* w: R2 d0 {' \36 } ) j/ s% B1 ?7 j, }
37
4 B! Y% Q0 s& W8 f38 void TEA::encrypt(const ulong *in, ulong *out) { 4 x. o3 f s2 \( P3 T! Z
39 N. |+ P- O7 t! C* h* S
40 ulong *k = (ulong*)_key; % z/ T$ j' b0 C# {4 s5 }* j
41 register ulong y = ntoh(in[0]); , g5 ]8 @: i; x2 j& G
42 register ulong z = ntoh(in[1]); 4 G7 S* w9 ^/ c3 G1 \1 M
43 register ulong a = ntoh(k[0]);
$ D$ B" Y Z- \. i2 P1 B% b3 S1 a44 register ulong b = ntoh(k[1]); 8 R5 n* d: P" f J, t0 ^# h6 m
45 register ulong c = ntoh(k[2]);
4 v- {- _" N, b46 register ulong d = ntoh(k[3]);
( z6 N# A. I% ?% r: R3 _ L47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ / ], o7 b; k' V Z7 z& Q$ \ o
48 register int round = _round;
9 S1 b b' }% l6 g6 p) d8 G! I49 register ulong sum = 0;
' V$ G, P2 t% S s0 `50 , e, B8 e/ C' |3 ]2 E
51 while (round--) { /* basic cycle start */ 5 R1 Y6 Q5 r C& X) a; m j% j
52 sum += delta; 7 s; _ X. f) y, y, L
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
3 g' n+ J0 i( S* A54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
. ? a$ s. N# B; O# Y t7 v55 } /* end cycle */ : X) F$ J6 c% P; {& }6 h0 {
56 out[0] = ntoh(y); , {: C) F4 Q& s
57 out[1] = ntoh(z); 6 J: d) }* ?& x
58 }
7 M @: F4 M% r: ~! m) S e59
0 u( V0 r8 M% m# H& H60 void TEA::decrypt(const ulong *in, ulong *out) { ) F6 i& ]: {' j; {% C. u
61 : D$ C+ H/ T1 R+ I- f; F& B
62 ulong *k = (ulong*)_key;
: g/ X1 _6 j0 d63 register ulong y = ntoh(in[0]);
$ `0 i6 F3 F0 m* Z& r" q64 register ulong z = ntoh(in[1]);
, ]6 J& F5 p& b. q65 register ulong a = ntoh(k[0]);
% h6 J- z7 p# H) e4 G4 ] |$ {66 register ulong b = ntoh(k[1]); ; {8 t! a4 C) _' m2 T
67 register ulong c = ntoh(k[2]);
9 Y7 z; Q: ]! l9 @1 E( g) }68 register ulong d = ntoh(k[3]); $ \& a& b* P/ S
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
- U1 Q9 z7 U) r ]. p) I* \70 register int round = _round; ( k2 V9 q" `$ Z7 q+ ^5 `
71 register ulong sum = 0; # U+ X/ \# r# a5 G3 D, E3 I R! ?0 f
72
( D1 o: g- y) `# @" y r- q8 w73 if (round == 32)
9 t% u* i& y1 l/ V4 x6 s; F6 x& b" e74 sum = 0xC6EF3720; /* delta << 5*/ ! u1 O) {8 D* j
75 else if (round == 16)
, a/ t! ^# o$ Z! R: {2 y( Q3 ?76 sum = 0xE3779B90; /* delta << 4*/
' r6 H# T7 y8 D. U. _& e77 else % d$ \/ G* V7 A. P! P6 P
78 sum = delta << static_cast<int>(logbase(2, round));
2 {7 E9 b5 Q6 [7 c. X79
1 |8 e. g# J6 B2 j M q80 while (round--) { /* basic cycle start */ / k5 u& P% R- T' j- b
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); 9 [! L D4 U: P) @ R1 s, V
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); + e4 F0 H) v; F* s
83 sum -= delta;
- d0 B) D l4 G" X84 } /* end cycle */
, s' `2 ]0 [/ l4 Q& w3 A85 out[0] = ntoh(y);
7 p h# Y2 _. A* }; W- ~86 out[1] = ntoh(z); 9 E5 o) u9 G# j# N2 c8 b2 r
87 }
$ t! E$ ?" V& n8 ~( X Y5 c3 f7 A; @ k4 U0 D, d
需要说明的是TEA的构造函数: * L" c8 Z1 f; S
TEA(const byte *key, int round = 32, bool isNetByte = false);
; {9 Q, r" C- j2 X" {; q) H1.key - 加密或解密用的128-bit(16byte)密钥。 * B/ i" _+ z3 @
2.round - 加密或解密的轮数,常用的有64,32,16。
, Z i8 J+ E5 N+ w" U1 G& d. T. d3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
% G# j# y% F6 Z" R
F: w: [- p5 {$ R2 Q最后当然少不了测试代码: |
|