|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
; K- o: |4 @* u9 L3 @+ V8 f6 ]1 O; v 2 #include <cstring> //for memcpy,memset
$ x3 g0 ], w$ M, C: N( ~3 s 3
, e: ]4 d/ @' E 4 using namespace std; " K% }& }8 z! ^, C( D
5
6 \, }" I. _; |: [2 V 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) 6 k1 W! F% Q, A( D# K
7 :_round(round) " D- a: c3 f; N- Z3 K
8 ,_isNetByte(isNetByte) {
2 {8 q) r* J6 e 9 if (key != 0)
4 N" H9 C' \! R- `5 f10 memcpy(_key, key, 16); $ {: O. v; h- ?; R1 w
11 else
- M* q3 J2 c6 r% _2 U" H12 memset(_key, 0, 16); 8 o4 u8 Z* B3 ^$ U3 p
13 }
3 n [) \4 w" C: u14 $ {: {- S# B( Y1 |+ F# {0 G# C
15 TEA::TEA(const TEA &rhs)
, z* [) A) q' t) q: p' ]( Z2 C16 :_round(rhs._round) 4 n: `) R3 i# d1 S. i
17 ,_isNetByte(rhs._isNetByte) { ! K# l" n* B! y6 w/ ?( p$ x
18 memcpy(_key, rhs._key, 16); * Q0 W, M, D4 B2 E5 G* G
19 }
# |: f9 B' N0 L6 K4 Q6 ^) N20 5 {! l5 Y1 L+ i( C$ D2 U
21 TEA& TEA::operator=(const TEA &rhs) { . N c) B8 } |1 w
22 if (&rhs != this) {
# F8 y& q: c& y) S23 _round = rhs._round;
, f- f- a' o, M: P: S, O+ C24 _isNetByte = rhs._isNetByte;
, P% I+ w1 Q3 J/ A0 ^: A4 x1 i25 memcpy(_key, rhs._key, 16); 2 u1 T# d5 @7 l( N: L/ L! H
26 }
$ _0 H( n8 x8 ~8 r$ f$ B) v27 return *this; 7 y( A2 ~2 C1 _3 r G& ~3 ^3 q, h
28 }
: {+ n+ Y% p2 l* Y29 3 u9 |, F2 J' B
30 void TEA::encrypt(const byte *in, byte *out) { 8 l: O7 x) i1 [( o+ ]; N H
31 encrypt((const ulong*)in, (ulong*)out); 7 j( a) u P; k. V! r2 |8 q
32 }
# \% c1 {* K. O' m" e33 ' ]1 y; ?7 k7 a" t! C
34 void TEA::decrypt(const byte *in, byte *out) { / {0 s5 }9 b+ n T: x" Q M% m: V
35 decrypt((const ulong*)in, (ulong*)out);
4 o$ T; S# M/ {: _7 k36 } ' m& o+ s% i/ R) r# `, M" d
37 , Z2 }- Z1 [5 Z/ ~! W3 K+ q
38 void TEA::encrypt(const ulong *in, ulong *out) {
7 `4 u2 E9 R8 I7 i39
2 \8 P% C9 j# p0 L+ H2 n0 d% n( p40 ulong *k = (ulong*)_key;
- ?" ~3 E: G' J! m+ w41 register ulong y = ntoh(in[0]); 4 `# `+ a& ^; T2 r' |5 I! l, x
42 register ulong z = ntoh(in[1]); , @- P3 z( w; y g. j" N* w) V
43 register ulong a = ntoh(k[0]);
* Q8 D0 R$ V9 M0 p" _1 K44 register ulong b = ntoh(k[1]); / r, d W- x4 V+ q
45 register ulong c = ntoh(k[2]); ! z J B% O4 K
46 register ulong d = ntoh(k[3]);
5 q- J& R4 Y! P* p3 \47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
0 W2 e( o' h) O5 r8 B# \48 register int round = _round;
" L) s* E9 f% L5 _6 g/ |# g) E, H49 register ulong sum = 0;
0 P2 T! @0 w$ B! s0 n; |50
* N6 I9 w3 U% Q% S1 }, l6 q7 N51 while (round--) { /* basic cycle start */
# q* ], M: t( j! H6 H52 sum += delta; $ F4 T# r2 z: {
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
. }+ d/ G3 o3 I0 q+ O: a! _# M54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
/ K V2 o7 I0 N9 ^55 } /* end cycle */
# g6 @* q* [$ h, @! W56 out[0] = ntoh(y);
, ]1 O9 F2 v( n: ^, [. V57 out[1] = ntoh(z);
- e2 Q- e8 H: l( }. b n& G58 } 1 e1 o4 i, g# r' t: A$ f
59
c) T0 U' U9 H: t' }" h, G60 void TEA::decrypt(const ulong *in, ulong *out) { 2 |& t. N$ S& P2 L
61
' Z& \: E. W% ]$ Y3 f# P9 N6 d& P, Q62 ulong *k = (ulong*)_key;
$ g+ V/ }$ J$ M2 Q9 B* r8 {63 register ulong y = ntoh(in[0]);
( m& g; q0 u1 Q+ s1 A: l64 register ulong z = ntoh(in[1]);
- ~; |; q) ~7 r$ W65 register ulong a = ntoh(k[0]); 7 ?" u7 w2 L' @0 s7 c
66 register ulong b = ntoh(k[1]); y) N! O0 r" R! a% I" E0 c
67 register ulong c = ntoh(k[2]);
. Y, b7 n6 U: n- Q68 register ulong d = ntoh(k[3]);
/ F+ @) |4 j1 t, V69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 9 y; H+ a; [$ K5 i3 ^; _
70 register int round = _round;
7 D1 j7 w+ q% Y u# d8 O71 register ulong sum = 0;
* Z0 t3 _7 Y) s/ ^0 k+ g72
4 U9 E7 h+ e1 }$ z9 Q1 a+ e73 if (round == 32)
, p" |) T; u2 k5 _3 ~6 b4 }74 sum = 0xC6EF3720; /* delta << 5*/
7 S' h' j# j/ V' e3 C( |75 else if (round == 16)
( e/ E' B, G$ ? k; |76 sum = 0xE3779B90; /* delta << 4*/ 6 x7 \4 @, [( e1 ^- \
77 else
# S) [6 f8 J. E W) z3 K( n78 sum = delta << static_cast<int>(logbase(2, round)); 8 j# _$ v* l; [1 u) Q8 R% ^
79
$ b6 N3 h$ u6 K, ?3 A7 A80 while (round--) { /* basic cycle start */
2 ?" v+ z( j4 P, x, d81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); 1 C1 {3 Y/ o/ L/ g/ v, T3 V
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
# n4 g# L* {2 V0 I. t$ N- E83 sum -= delta; 5 e" S& n; t9 L4 d) ^1 e
84 } /* end cycle */
3 z# J1 \/ S1 c4 N& |6 u85 out[0] = ntoh(y); # V2 U7 v6 y: T/ `4 t
86 out[1] = ntoh(z);
: a% j; E" G; z$ Y) J4 \$ n6 j87 }
( ^! r7 J! I& ?1 V) k2 }' v/ S
+ }4 |* `& r3 X! e% \需要说明的是TEA的构造函数:
7 y4 X1 m6 D4 |3 @6 XTEA(const byte *key, int round = 32, bool isNetByte = false);
6 O6 P/ I2 {. U; b8 |1.key - 加密或解密用的128-bit(16byte)密钥。 4 B. J$ E# d, r8 j8 [ m; _
2.round - 加密或解密的轮数,常用的有64,32,16。 0 G+ g6 v" }0 X2 [' _
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
& L2 [% s4 m: h1 V/ i7 k) R5 k8 W; @/ m" o; _' f
最后当然少不了测试代码: |
|