|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
. Y( h, e. q. }9 x7 m: H 2 #include <cstring> //for memcpy,memset
, z& y" ?( U" W: [7 R 3
5 E3 T ]5 y( i 4 using namespace std;
! O( g( p! x) j4 ^ 5
- S; `3 s* Y9 z; D$ G 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) 0 C* ]* A: [. z' ~8 o( ^
7 :_round(round) 1 F8 Y3 P* c2 K* x) {% N4 ~2 ?. N
8 ,_isNetByte(isNetByte) {
# A7 B7 w% `* T, }+ C 9 if (key != 0)
4 u& d! K. D/ b10 memcpy(_key, key, 16);
* i. i# z) `9 S; u4 q11 else ; P0 `8 B0 P, e! ~
12 memset(_key, 0, 16);
: \: r P( d+ R: G9 L. I13 }
: U7 H3 `- M/ p0 Y( F14
+ ?$ |" J. N* C% K; a15 TEA::TEA(const TEA &rhs) + j% j% d% ]( q$ `' K# z9 W+ j
16 :_round(rhs._round)
8 |4 ^: l! p- d" ?* A$ \17 ,_isNetByte(rhs._isNetByte) {
1 g9 D: {0 T' |& E! _) u; s5 q& a18 memcpy(_key, rhs._key, 16); ; l- ~. O% U/ w2 A$ o
19 }
y1 Z' T5 V# Z3 \20
5 Q" T+ U) Y8 b0 N9 `21 TEA& TEA::operator=(const TEA &rhs) { . s1 L4 s& `% E* y+ A+ G; v0 N
22 if (&rhs != this) { ; ^0 r, p+ ]! c/ E% L1 w
23 _round = rhs._round;
' g& x D2 m+ o) @2 Q% x24 _isNetByte = rhs._isNetByte; 9 D, _# @: S$ V4 @2 B% F
25 memcpy(_key, rhs._key, 16); ! T& W, W; g1 X3 ]0 s: I; M
26 } " _5 k" z3 i. _3 B! T1 I+ b
27 return *this; 9 o% d2 D1 [& E
28 }
( L& X: n+ B8 L0 a6 g. u29
/ C/ J6 c# { G$ D30 void TEA::encrypt(const byte *in, byte *out) { % L( o6 C2 n n$ G& c
31 encrypt((const ulong*)in, (ulong*)out); / S/ t/ y G, u- s, ]
32 } 1 J+ o! W- |# u
33
& {) r1 O$ |4 e- }$ m34 void TEA::decrypt(const byte *in, byte *out) { 4 l" C: ^6 |% p" K
35 decrypt((const ulong*)in, (ulong*)out); * B$ \2 O" U: \. {
36 } 9 f; M) ~: P( F0 Z8 Y; z
37
( e3 m; }, F0 A4 g' _+ ]38 void TEA::encrypt(const ulong *in, ulong *out) { % m9 o2 \) @, d; U
39
0 b# { Z, m' m! i) ]. M! g5 E9 \40 ulong *k = (ulong*)_key;
$ \ F5 F/ n- i6 t' F41 register ulong y = ntoh(in[0]);
8 J( p* P( }2 u/ _$ G, S7 t42 register ulong z = ntoh(in[1]); 0 o/ F+ M( R, `. Q' k$ ~
43 register ulong a = ntoh(k[0]);
3 ^! _: a4 F5 d5 ^9 L44 register ulong b = ntoh(k[1]); 3 c% R- n. S" K; m; ]# m$ C
45 register ulong c = ntoh(k[2]);
: `: \$ b* }; b4 `* T3 y2 a46 register ulong d = ntoh(k[3]);
* l' W! I0 T% @0 Z47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
8 \8 n' N7 U/ i3 V+ r48 register int round = _round;
3 N B" p9 }$ p49 register ulong sum = 0;
! Y1 E$ T# `& A50 , {- V8 B' j; d* }) H3 d! I
51 while (round--) { /* basic cycle start */
' J, D- @+ N+ e) D: s0 W2 `" E52 sum += delta; 0 o5 R( T. g6 k' }! z
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); ( W: ^/ V# a) G
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
3 i( d$ }! j% s( H7 b55 } /* end cycle */ , b+ q7 _- M% Q& t
56 out[0] = ntoh(y); % `, \6 z. w( l
57 out[1] = ntoh(z); 1 C% ^* D7 }8 Z& B. W9 q
58 } + I) X: g! M! ~; h" A3 v# ]5 J
59 % x' t0 n6 W1 V8 t2 c8 C% A
60 void TEA::decrypt(const ulong *in, ulong *out) {
8 z: @0 o2 S8 b- r( a, W61
( O4 O% P" Q3 h7 c4 [62 ulong *k = (ulong*)_key;
9 \& i1 L- m& y- U63 register ulong y = ntoh(in[0]);
. Q, e! d' `; Q5 J# a0 X64 register ulong z = ntoh(in[1]);
# V" k: E# ^7 E. r, x7 H p! L65 register ulong a = ntoh(k[0]); # [# K4 }, z1 m, v
66 register ulong b = ntoh(k[1]);
- o3 z% d( Z1 c; \67 register ulong c = ntoh(k[2]); ' _, v5 d% `, o' a
68 register ulong d = ntoh(k[3]); 7 m' [, u1 B7 R3 V# n( \
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
0 a( J1 o V% B8 O" t# L70 register int round = _round; & U# h9 q1 H n! |& I1 B
71 register ulong sum = 0;
3 S% \3 j3 U' w; C) U. N72
/ f% g ^, g) g1 N3 ?# Q5 S73 if (round == 32) + ~" R1 n# ]$ b ?7 }
74 sum = 0xC6EF3720; /* delta << 5*/ 8 |* u; x; p& J" @ _9 V0 }$ j
75 else if (round == 16)
3 A8 I6 F$ R/ s) P76 sum = 0xE3779B90; /* delta << 4*/
) G# O! e- w# \( V) [77 else
! x/ L$ l4 ^! ?$ P3 N* \; @+ V' v: S78 sum = delta << static_cast<int>(logbase(2, round));
( I a: ^: b6 S, E# D5 q9 W79
" g" g0 h7 S; U4 z80 while (round--) { /* basic cycle start */
5 l4 }: L* ^& J& A& R2 H. [ {81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
* q% B! }& E G0 O82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); 6 e; o# B! h8 w6 Q
83 sum -= delta; ; G0 E1 q4 V9 Z
84 } /* end cycle */
6 {( r; b4 N. q2 X" |: y& j85 out[0] = ntoh(y); ; F4 _5 z: h3 Z
86 out[1] = ntoh(z); $ x5 P) Q+ L8 }; o; p5 @
87 }
( Z4 J- [" E% @
2 B/ s( t7 k$ x* Y) u7 X8 r需要说明的是TEA的构造函数:
# C( W G Z5 r8 N& V% b, N7 v; I3 @3 cTEA(const byte *key, int round = 32, bool isNetByte = false);
/ r2 R, V/ ], P d7 X/ s! t* t1.key - 加密或解密用的128-bit(16byte)密钥。
4 u- c$ o# t `2 A. @2.round - 加密或解密的轮数,常用的有64,32,16。
/ U; x; {3 v& Q: c+ Y3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
# f# z7 [( E' G
1 |0 W q0 }: r4 b5 h2 z$ X最后当然少不了测试代码: |
|