|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" ; `/ h5 w" w6 l6 E
2 #include <cstring> //for memcpy,memset , `7 j) x" N, v5 u% R7 D+ u
3 : F0 x3 `% k& Q3 |* @( Q; }
4 using namespace std; , Z1 [2 u4 h! Y* w+ ]+ b8 ~) u& S
5 3 ~6 d; `; t8 ?; [' c2 h O
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) : v4 x% E9 |9 B U# E" |
7 :_round(round) ) k" A! K% i, `
8 ,_isNetByte(isNetByte) { & Q! M7 }" n0 _0 E$ I; H
9 if (key != 0)
$ A8 a) j u. d* V1 { b+ f8 ^10 memcpy(_key, key, 16);
7 ^! t8 `" ]4 P% _6 d! H9 P/ D11 else 4 b( t# o1 \" ~8 i& H" u
12 memset(_key, 0, 16); 7 F' y5 @3 ~. Q0 j4 z- X
13 } ! O& i& G( `% |
14 " {2 S, }7 |, A5 ~- }
15 TEA::TEA(const TEA &rhs)
3 G( B' Z! j" K5 x4 T+ }1 y9 L; L16 :_round(rhs._round)
: G; N; Z5 p2 b+ l# |17 ,_isNetByte(rhs._isNetByte) {
; F! y, P) _: R2 ]1 S( C6 ^% ]18 memcpy(_key, rhs._key, 16);
7 j3 T2 M" L' }' i1 b19 }
- _3 `( M; f- r# T7 s* U20
/ n& y k2 H a1 P. j. i21 TEA& TEA::operator=(const TEA &rhs) {
9 n1 s7 [+ p% r2 _5 T5 m22 if (&rhs != this) {
" u2 X, K5 F7 I z23 _round = rhs._round; : \2 s0 B" e' X4 F( `& i
24 _isNetByte = rhs._isNetByte;
% g! ?& y3 g) N8 d$ K25 memcpy(_key, rhs._key, 16);
8 l$ C( N, g, a( E" Y26 } 7 S' `1 k7 n' l
27 return *this; 8 x* M& G( r- e* x1 y4 ]
28 } 2 e; d6 z" i+ F! S0 ^
29
8 C" \$ ^, m& y( p, [30 void TEA::encrypt(const byte *in, byte *out) {
. z w2 Y1 f( u1 D1 l31 encrypt((const ulong*)in, (ulong*)out); ) q4 m* T1 U1 ?! i! q# Z
32 }
8 o% p; N, y! g- E6 m5 K% |33 ! V; Z" x% ?: {
34 void TEA::decrypt(const byte *in, byte *out) { 8 d2 f' s* C6 P# J+ o9 e& q
35 decrypt((const ulong*)in, (ulong*)out); % J4 ]7 g c2 _4 f6 ?
36 }
/ t9 H7 b: s& H) o! n9 W# g37
& a3 Q8 o7 K3 [* h3 V5 b38 void TEA::encrypt(const ulong *in, ulong *out) {
/ }0 O$ y% M( B% j4 q39
% ]$ l# F, M' u8 m6 M40 ulong *k = (ulong*)_key; 8 o; w& o, @# N/ {% @6 }! f
41 register ulong y = ntoh(in[0]);
) P" r+ u4 S. M42 register ulong z = ntoh(in[1]);
3 N+ ~# M% A- Y+ C43 register ulong a = ntoh(k[0]); 4 A- a; x6 C* s% D, n
44 register ulong b = ntoh(k[1]); / i8 F7 @3 ~) j* \: G0 h- i4 _
45 register ulong c = ntoh(k[2]); / z! Y3 i( J3 ]7 _
46 register ulong d = ntoh(k[3]); 2 _3 b1 T' _1 Z. ?: I6 t
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
: R4 V! l. i" P0 ]4 h5 S4 Z48 register int round = _round; }5 n1 q9 N! x
49 register ulong sum = 0; ( e" l& T$ l. w. t8 n3 ]' z$ j
50 3 r6 n2 }" N, x' G# N) c
51 while (round--) { /* basic cycle start */ 7 U! Q" t+ [; B% [7 c5 Z
52 sum += delta;
! D; N3 M- a6 h4 P53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); * u+ W8 f* W2 H V% H8 \, R: y
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
8 o* R v: x3 ?55 } /* end cycle */ * q' \6 q0 ~5 u( m8 ?
56 out[0] = ntoh(y); * o: ?! |% ~% s7 E- T
57 out[1] = ntoh(z);
O0 f1 Y5 o k( i+ ^58 }
7 N! ]2 Q8 i# G7 T0 k {2 v* C0 d59
$ P# W1 X) M; U5 o7 F2 b7 T60 void TEA::decrypt(const ulong *in, ulong *out) {
. D# @5 U! y" V7 L# X6 }) e61 8 N: W% @+ x6 }4 x* N8 {) ^% O( `$ H3 o
62 ulong *k = (ulong*)_key; ) \) b8 |5 [1 s _
63 register ulong y = ntoh(in[0]);
4 D8 t9 e0 F* L3 u6 N! B" Y8 V64 register ulong z = ntoh(in[1]);
( N# L' @8 q, J( u+ t3 b65 register ulong a = ntoh(k[0]); 3 {5 S% r, {4 ]: w
66 register ulong b = ntoh(k[1]); 5 `- u, B! d6 d/ [& ]; y
67 register ulong c = ntoh(k[2]); l# c. \# R1 A" m( o- i- _$ `
68 register ulong d = ntoh(k[3]);
, e* x% ^8 [2 l6 _* R' g6 w+ \; X69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
, \* n; K; @& x. ~5 Q9 I# s2 N, U70 register int round = _round; , U- U# b# q9 B
71 register ulong sum = 0;
2 G* q9 l7 ^% S8 [, ~/ I4 o72 9 `% W; O* j& U5 d
73 if (round == 32)
" N2 }! S$ J+ L8 x! d( y74 sum = 0xC6EF3720; /* delta << 5*/ ( g% v( r d2 f0 ]9 ?. ]
75 else if (round == 16)
0 G" `, ]7 ~' H: i, p- |76 sum = 0xE3779B90; /* delta << 4*/
: f& N; U$ O7 T' z' K3 v( ?77 else
7 f, j0 K \+ v) Y78 sum = delta << static_cast<int>(logbase(2, round));
" s0 Z- o. q; P5 M5 `7 u79 ! y; w- n' Z0 z- f& E( q' ^
80 while (round--) { /* basic cycle start */
( W4 A4 {1 X8 y0 u81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); & n5 c' A- @) B" ^. Z
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); i2 L; a* }( i- y* i4 O7 [( @( A
83 sum -= delta; 7 G6 g0 g, e) `2 l
84 } /* end cycle */ / y0 T2 z1 X* ]) t- k5 e t
85 out[0] = ntoh(y);
& S/ c) l# ?3 ?# U$ o86 out[1] = ntoh(z);
/ A! i% R# Q2 S5 R87 }
8 c$ X6 t+ D, U/ E: y6 U6 P& j4 O" Y; b
需要说明的是TEA的构造函数:
1 P0 V7 E0 u: _; CTEA(const byte *key, int round = 32, bool isNetByte = false);
: O0 g8 U9 V* V1.key - 加密或解密用的128-bit(16byte)密钥。 + d9 d& J& `8 }' ?" a6 P
2.round - 加密或解密的轮数,常用的有64,32,16。 ) q* K9 o* j' r. S
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
; z |9 E( C1 M8 s/ D8 b3 w6 E& W3 \3 O9 M" V1 L
最后当然少不了测试代码: |
|