|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
' O$ I& ^3 q. A. e& o, J. q! q 2 #include <cstring> //for memcpy,memset 9 x( Y% P, _! L2 ^ s4 @( c
3
2 v# P4 u5 V2 p4 x 4 using namespace std;
' G* p( \. X5 l* e: C+ B 5 8 f% x, P9 G; Z4 o+ L
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
( A& V6 K9 e# l' p+ R1 F 7 :_round(round)
/ R% @7 `6 a8 K 8 ,_isNetByte(isNetByte) { 2 t5 V M# W3 m9 w6 Z+ z/ I- @, @) X
9 if (key != 0)
; s& \6 k" r7 t; V. p10 memcpy(_key, key, 16);
: ]" d% ^& y2 f. o5 b11 else ( A" [9 T/ f$ d
12 memset(_key, 0, 16);
* X7 @# k) e5 O, w8 r6 M9 x4 h2 z13 } ( k% z% i2 Q6 l( t
14
1 j/ C7 B$ b6 r' Z- }+ E15 TEA::TEA(const TEA &rhs) # m$ N! m! K" N9 ^ t
16 :_round(rhs._round)
+ [0 [2 r1 g$ z9 a% F$ M17 ,_isNetByte(rhs._isNetByte) {
) Y) i% Y* `6 P! X$ a18 memcpy(_key, rhs._key, 16); , e' w7 f# @! W
19 }
" ~9 R h* W& F5 d; J' G4 E0 i20
- `" x2 O! v( b21 TEA& TEA::operator=(const TEA &rhs) {
4 Y! u9 ?8 B. [2 S22 if (&rhs != this) { # A7 X: }- u. [% I; V+ ~& G6 i
23 _round = rhs._round;
2 K, _8 }- h- g$ n! c9 Q9 _24 _isNetByte = rhs._isNetByte;
. v3 Q/ T5 c1 N9 M1 l. v+ n0 N: Y25 memcpy(_key, rhs._key, 16); ! m% r) }& @$ A9 [
26 }
+ H; d( E1 r0 `5 R) v! H* r27 return *this;
+ R/ J. {2 H6 q0 r3 n28 } & s* v+ v4 c0 m% \
29
$ H, M* L+ W2 D3 v" D6 `1 B0 c30 void TEA::encrypt(const byte *in, byte *out) {
0 e S! a4 c; D7 V* r31 encrypt((const ulong*)in, (ulong*)out); : b) X4 {; a; L; |
32 }
, K, @. @$ G7 O& [9 ~, z4 ^0 j; r33
5 C& u" ^4 ?3 g5 l( K34 void TEA::decrypt(const byte *in, byte *out) {
& _' O, n! A$ I: `- C4 ^35 decrypt((const ulong*)in, (ulong*)out);
7 K! S" e. I! W9 H9 X0 M36 }
4 e7 f+ i9 S+ `+ a( W5 Q, Y37
- E. B+ {& C9 D0 U9 w38 void TEA::encrypt(const ulong *in, ulong *out) {
5 V9 O- l- }5 e! }39 7 z& j0 n1 M! D! r' \
40 ulong *k = (ulong*)_key;
3 x! \6 U# e2 G9 R41 register ulong y = ntoh(in[0]); ; m+ Q7 e3 s/ i6 e: k# {
42 register ulong z = ntoh(in[1]);
2 G( ?1 c' |0 X* m. j* L* J5 X( B' F6 l43 register ulong a = ntoh(k[0]);
0 _) e2 J1 W$ n& k44 register ulong b = ntoh(k[1]);
! h" E# L6 j+ g9 d45 register ulong c = ntoh(k[2]);
; i8 R' @* R8 V9 D; O1 @, F: Q46 register ulong d = ntoh(k[3]);
) S0 P, G; O! _) g" D2 x) }, m/ `; L47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
: g; j$ N5 ~# A48 register int round = _round; w2 ?0 ]- ]: z* C! t E
49 register ulong sum = 0;
2 ~8 s" `0 J- R8 T! j" ]50
7 s5 {9 }9 e% }! Q51 while (round--) { /* basic cycle start */
p0 G3 l. ]: p52 sum += delta;
0 j% R/ |- m; F" C53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
) U4 F; Y$ C' n9 _' u/ ?5 L54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
) F2 [# c$ ` ^ V55 } /* end cycle */
7 o* v( c% t& U% [' ?56 out[0] = ntoh(y);
- x6 O" O+ n" A" O6 I1 N57 out[1] = ntoh(z); ( d8 V4 A) h! ?5 {( c& v
58 } : n& i" P4 |7 c7 p. |$ B8 L: M
59 # k9 a2 Z% W, E
60 void TEA::decrypt(const ulong *in, ulong *out) {
# E4 f" X- Z' K" H& l61
3 f ]" u, v. c; k$ i7 [62 ulong *k = (ulong*)_key; + j9 J, y/ f% }$ J# W3 G
63 register ulong y = ntoh(in[0]);
+ E- e: x) R+ v7 X. D64 register ulong z = ntoh(in[1]);
: B2 S5 g( ^: S; i2 L65 register ulong a = ntoh(k[0]); ) L5 a) d) x+ x) \
66 register ulong b = ntoh(k[1]); 7 K, d9 b# n3 F; v' g- o) q0 @
67 register ulong c = ntoh(k[2]); ( u. D' p; f) w- B
68 register ulong d = ntoh(k[3]);
% \; W3 M9 P8 }6 Z8 Z% G69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 0 i; [& t t' V3 T8 J' x7 x/ Y
70 register int round = _round; ) l$ f, Y/ A) _5 P) }. W
71 register ulong sum = 0; 4 y( c8 L# o7 w; K' u+ D
72
G' j' ~7 P. b. E% ]73 if (round == 32) ' v/ ?& A2 D5 b/ `9 ~" V
74 sum = 0xC6EF3720; /* delta << 5*/ % _# Q6 M2 ?+ N V& p, a
75 else if (round == 16) - K+ g5 j8 b5 y N+ C$ t
76 sum = 0xE3779B90; /* delta << 4*/
0 e% \+ J1 l4 a( A77 else
3 M1 e' A# y$ e4 l" C7 X7 i& N78 sum = delta << static_cast<int>(logbase(2, round));
o) H0 f: c1 n- @0 y* v, T k79 3 w/ t4 e2 W# S% f5 |5 f1 @* \
80 while (round--) { /* basic cycle start */
2 A: j% P6 Q( e2 k" q$ y9 A81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
, h* c+ ~' P1 Q8 @82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); ; \) T5 d/ a# |: A& |( a! S) D
83 sum -= delta;
0 E4 [9 _$ G) c3 O; E84 } /* end cycle */
. c& r+ X, I) T. x4 s. f85 out[0] = ntoh(y);
/ ]$ v0 {% G+ {86 out[1] = ntoh(z);
! ?& \( K; s5 L6 J$ z87 }
# B9 g4 _6 [6 X! C6 a4 m1 J
# S: F1 Q0 _7 w' A. l需要说明的是TEA的构造函数:
) w+ l* j& f$ X# xTEA(const byte *key, int round = 32, bool isNetByte = false); % |' E ?. {/ ~/ m5 K
1.key - 加密或解密用的128-bit(16byte)密钥。 . l8 T9 ~% L! _% P0 O) s
2.round - 加密或解密的轮数,常用的有64,32,16。
/ I9 n3 s' q( ]& T& }1 l6 f3 V3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
# f% \+ l0 J8 T8 o8 n4 j/ e7 _, b9 k) X
最后当然少不了测试代码: |
|