|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
/ p$ r- m5 G- T. b 2 #include <cstring> //for memcpy,memset
# L/ U' @2 p1 }- ~ 3 / ~1 y! {! T3 D) D" v
4 using namespace std; 9 S2 K3 w7 x) u+ t( t
5 $ ~; U2 A0 G* ^3 w3 W6 d# r
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) + R% z9 Y: t4 M/ r2 ^- I
7 :_round(round) 3 Q# ?; Z5 W) L1 q; e; ~
8 ,_isNetByte(isNetByte) {
' N$ n3 Q7 O `/ l. L4 _ 9 if (key != 0) . C5 I, r0 T9 z. ^0 w& A% J3 r2 D4 z
10 memcpy(_key, key, 16); . l6 o, x9 u) O p. S
11 else
9 ]8 ^+ w8 E. Q Q9 u12 memset(_key, 0, 16);
3 H5 z- ~, Z/ M8 B/ ]: ^13 } 9 }" ~6 n1 F! u
14
3 f" n. D/ o. M15 TEA::TEA(const TEA &rhs)
& E( a( _1 q8 M: l1 ^9 |- i16 :_round(rhs._round)
7 U0 j$ R! c% `4 b17 ,_isNetByte(rhs._isNetByte) { # a/ }: e& I9 b ?! u
18 memcpy(_key, rhs._key, 16); + _, }* ~2 }( @4 C: b& U
19 } & Q+ o6 n; p. C/ G, W& O/ c
20
, }7 E* s2 Y6 g$ t, d' M0 z21 TEA& TEA::operator=(const TEA &rhs) { " V* r7 U4 b h& z- p+ W. ?: a' o/ y" {
22 if (&rhs != this) { . [( j& h( p, @8 V
23 _round = rhs._round; ! X9 ~; H0 B! r$ [; |9 ?
24 _isNetByte = rhs._isNetByte;
) J( j2 ~: s" T5 i% T6 g25 memcpy(_key, rhs._key, 16); + ~* O2 C/ M: I4 ]& Z* F* t
26 }
( ]% y( w# K O' \9 ]- w( o27 return *this; % M+ \" ~' V4 Q+ a( i6 W# @( b
28 } 9 B( G K- F9 `( c& r6 D+ q
29
. f5 U/ c, s2 R/ l: m$ v+ R, G30 void TEA::encrypt(const byte *in, byte *out) { 2 u! \0 L( d" x
31 encrypt((const ulong*)in, (ulong*)out); ' ], S9 I1 x2 B0 E0 l$ l- G& V: H
32 } , t- m( T" o W5 [# V
33
3 s" E+ ?, i5 t$ h" K+ J34 void TEA::decrypt(const byte *in, byte *out) {
7 G5 T, O7 M& ~3 i/ D- L35 decrypt((const ulong*)in, (ulong*)out);
$ X, T1 B) g7 X36 }
" {2 x* N* C+ Q% S; E37 * q& W5 i' r. o& O; Z2 ?- ^
38 void TEA::encrypt(const ulong *in, ulong *out) {
0 a' x# ^, Y% p0 R: i3 e: b5 e39 - H% \# a# b4 M( g% w1 N) h8 N2 s
40 ulong *k = (ulong*)_key; 8 m) Y) A' L1 M' d- ^
41 register ulong y = ntoh(in[0]);
5 }+ I x1 U, r1 e/ T" k4 Q42 register ulong z = ntoh(in[1]);
, \. }& l: T/ K& W" r43 register ulong a = ntoh(k[0]);
* M* s. `7 b2 z% l44 register ulong b = ntoh(k[1]); 4 X2 J/ F. j' g4 J8 n1 ?
45 register ulong c = ntoh(k[2]);
' K2 _7 b" V; o9 K5 p2 J46 register ulong d = ntoh(k[3]); 7 m( C# X3 [" M( M) H) a
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 0 f" S( a( l& I4 E0 S: E! g# O
48 register int round = _round;
1 N' n4 y# V! U: I( Q* Q5 t49 register ulong sum = 0; * C- Q+ l: u! e! v: W! E* [7 I5 t [ v6 z
50
9 b! i1 W( X7 q: [; ]2 g51 while (round--) { /* basic cycle start */ / \! z" L4 Q1 k/ ]9 }
52 sum += delta; ; X% F5 E* H4 A- ~) {8 H' D
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); , S; }+ o. U7 ~2 z+ Z, B, ^0 ^' ?9 Q
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
9 P7 c$ X6 t7 q55 } /* end cycle */
+ ]' E# ^+ d: q f56 out[0] = ntoh(y); / a7 R8 d$ B% X7 n0 l; s1 B
57 out[1] = ntoh(z);
/ E6 e/ _: u* W0 j+ `# X. t58 } + R1 t# E3 W O! ^7 L+ [
59 / V: _: v* Q* \4 _- g
60 void TEA::decrypt(const ulong *in, ulong *out) {
' t& M5 c+ H0 C1 g61 . P1 ?& v* A. v
62 ulong *k = (ulong*)_key; ' E( _6 y, k! o4 A- f: t. |6 y' k" D+ W: t
63 register ulong y = ntoh(in[0]); $ ~; h6 S- @* Z5 p, h
64 register ulong z = ntoh(in[1]);
/ k7 k& `$ A; ^2 M5 b! y7 E+ `65 register ulong a = ntoh(k[0]);
. T1 g* g) e8 q66 register ulong b = ntoh(k[1]);
6 g: p# C+ M4 d4 d5 T9 t7 a67 register ulong c = ntoh(k[2]);
9 s4 t% ^ ]- o% k68 register ulong d = ntoh(k[3]);
! h4 c: b0 f4 l" \0 C69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ . S3 J( p' e5 M, g. V+ C0 z
70 register int round = _round;
& \% u/ O# @6 d9 i1 j71 register ulong sum = 0; 1 L1 T5 I7 o- x( v& V
72 ) l/ X+ {' X. M' A( d5 S, {- `
73 if (round == 32)
" k1 i7 X' Y: X5 d: a* X74 sum = 0xC6EF3720; /* delta << 5*/ ! ]7 x, l3 \4 N( y' J
75 else if (round == 16) 3 Q) U5 b0 \, v, C. {( ]) ~3 _
76 sum = 0xE3779B90; /* delta << 4*/ 2 W8 N8 c) \ o8 D5 }/ Z4 m, W
77 else % a2 `4 U" v* K
78 sum = delta << static_cast<int>(logbase(2, round));
8 ~& O/ o# Z8 Q$ J0 Z4 Q8 G79
' s6 W; M" n7 C* o! R80 while (round--) { /* basic cycle start */
S% {( b% y+ e) U$ X! |81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
# ?4 H5 }. k0 g$ g: N! l82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
0 @$ ?+ |: ?7 f' m2 U/ f9 v4 q83 sum -= delta;
: W7 i! W+ y6 n3 c84 } /* end cycle */
9 \7 {+ J$ G7 |+ P& W85 out[0] = ntoh(y); / Y: c0 N5 v, Z, T" s. q" e7 v
86 out[1] = ntoh(z);
( Z5 h/ c& l9 Y( m87 }
, Y8 G+ P2 B Y% O. M. f; M
. u" T1 C, I4 h5 y0 w" j需要说明的是TEA的构造函数: ! {( D# x7 ]& G; H2 q" J: S* r ^
TEA(const byte *key, int round = 32, bool isNetByte = false);
, I) N2 G$ I' s; s: D5 n+ l1.key - 加密或解密用的128-bit(16byte)密钥。
2 u* X; h; Q" z9 H+ {+ H" y' d2.round - 加密或解密的轮数,常用的有64,32,16。 ( C8 e1 S( ?. ^
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
- T$ \$ z9 G& U$ K9 {# g% E" ]( j" C/ W2 D
最后当然少不了测试代码: |
|