|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" . {' ~1 j j2 A
2 #include <cstring> //for memcpy,memset
& _. W/ s& s" P/ K 3 5 [$ g5 Q! A) ~ u1 |- X
4 using namespace std; + q, y S" ~# |0 P( N* K
5
- f* J" J& F6 ?) t y5 T 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
, v& z7 V1 k/ \( } 7 :_round(round) & A" |/ w: Y' j7 {. }3 e) }% C: U
8 ,_isNetByte(isNetByte) { 6 E+ |9 n& i' x9 ~, _
9 if (key != 0)
* G$ [. |. E8 ~' f0 {4 N' ]4 D10 memcpy(_key, key, 16);
8 D$ m- F1 f8 G11 else . x& m. j' W) f8 K2 I0 I9 X' i! f' ^
12 memset(_key, 0, 16); 8 y0 q0 P4 D+ ~- w$ T% M, O
13 } 9 E2 z! ^+ d" j+ s/ S
14
+ {& ^ w% I* K: C8 j) L, Y ^15 TEA::TEA(const TEA &rhs) / b% C- k- }# `$ ~3 i
16 :_round(rhs._round)
( ]$ a$ g" N% k/ }7 V3 Y7 n17 ,_isNetByte(rhs._isNetByte) { * N$ O* _4 Z! F p0 N) G8 q y
18 memcpy(_key, rhs._key, 16);
: G6 c1 ?- k# |1 S: h7 G* [. c8 q19 } & U2 o' N' G7 ~& k$ V+ N' g
20 6 }* _9 {7 _. Y7 Y
21 TEA& TEA::operator=(const TEA &rhs) { & w. l7 b/ N* `9 P2 A
22 if (&rhs != this) {
2 M0 H- a6 a( Y, f% j% N% i' O0 j23 _round = rhs._round;
2 U: R1 |' W7 H- K, S24 _isNetByte = rhs._isNetByte;
, |& V/ T1 s/ t7 l' C! s; i- U25 memcpy(_key, rhs._key, 16);
* N& Q3 S" P& Y' F3 r8 {1 i( q2 m26 } $ [9 a8 Y: H4 n A- ~* i* S
27 return *this;
8 W! z6 ]9 q2 `* j6 u- ~5 ^0 B28 } * c8 r6 k7 J$ h$ O5 I# @
29 , x/ y8 F5 A& C( k- ]% v& U$ U5 c/ w" p
30 void TEA::encrypt(const byte *in, byte *out) { 7 m* P7 O. W: ?5 @, X
31 encrypt((const ulong*)in, (ulong*)out);
$ ^+ Z2 `; P' {# S$ c& a32 } : C, R2 N- `( V" o" n4 k& |) ` b
33
$ x* N7 N% r3 D34 void TEA::decrypt(const byte *in, byte *out) {
$ B; D$ x$ x- i% f) G) j/ M& }. t0 _35 decrypt((const ulong*)in, (ulong*)out);
# a7 h J2 B; \36 } 0 i" g- F9 x+ O& N% n
37
% ~1 v4 C# U7 N/ s38 void TEA::encrypt(const ulong *in, ulong *out) {
$ d7 J0 C% _+ M* l( G; |( |1 ?39
3 z9 T: B9 N* l40 ulong *k = (ulong*)_key;
' B7 ~- [1 |2 a( ]41 register ulong y = ntoh(in[0]); % g: {* B4 y; W9 ?+ U
42 register ulong z = ntoh(in[1]);
1 W4 \ ^7 b6 b8 K3 T/ L5 o7 y# F& e43 register ulong a = ntoh(k[0]);
' T# B/ s, T4 U: k0 M8 O44 register ulong b = ntoh(k[1]); ( v4 E3 x! v% \ |0 p; n! R7 N& e& Z
45 register ulong c = ntoh(k[2]);
* e [, K. _/ H2 D: _46 register ulong d = ntoh(k[3]);
4 C. I$ c5 U1 _ V1 B; B( q47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
$ S/ s0 @) C4 b48 register int round = _round; 9 s2 O; p9 J- b6 |! n" W7 ?; L* L
49 register ulong sum = 0;
4 m* r2 i4 C( V' P. U50 6 A: P; x2 A. Z0 x% j
51 while (round--) { /* basic cycle start */ 7 U- I3 y) F. F% }9 g5 A; c
52 sum += delta; $ J3 U8 s: K" b3 f
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
1 F" V7 B) a2 P4 Q54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); 1 J& S0 G* j; O$ J+ z! Q
55 } /* end cycle */ . X" M' d9 X9 O/ @
56 out[0] = ntoh(y);
k- {0 N5 C% p5 c: Z57 out[1] = ntoh(z);
* h* v! V+ H7 o1 C58 }
! ~( M# k3 z2 a f, X7 w59
" A5 U% n7 }, r3 f% H3 P60 void TEA::decrypt(const ulong *in, ulong *out) {
. n8 x! F' }7 ?5 Z% ^ w0 [61
4 w8 v# e E! v0 U+ p& d2 M9 y5 ~62 ulong *k = (ulong*)_key;
. @3 ^. _+ M* j- ]/ q63 register ulong y = ntoh(in[0]); # s# M) Q& t; l3 T* _$ E% l
64 register ulong z = ntoh(in[1]);
/ h# P; S$ a: F7 g65 register ulong a = ntoh(k[0]);
' h+ Y: O4 h% D8 I% E7 g, A. A66 register ulong b = ntoh(k[1]);
$ z' C7 B% I4 W) \67 register ulong c = ntoh(k[2]);
1 Q, n( r6 m! d68 register ulong d = ntoh(k[3]);
* N- L8 ~5 |2 s% B& }69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 4 i9 u1 Q# Y7 n/ b: i
70 register int round = _round; * W$ [( O5 ?3 B' b
71 register ulong sum = 0;
7 R) _" X1 A( T; A: r72
R# \2 g. t) X a ~: h9 {73 if (round == 32) / S d1 b7 q" K: d# A' [4 p
74 sum = 0xC6EF3720; /* delta << 5*/
8 Q1 m7 N( |3 x75 else if (round == 16) $ ~7 i; @. R4 L7 v) C
76 sum = 0xE3779B90; /* delta << 4*/
% f [+ L& {0 S- G77 else
# v) X0 ~/ c# J7 [78 sum = delta << static_cast<int>(logbase(2, round));
( a- B; T# `3 y# P: Y" a+ L79 , m2 I( b1 F) \# v# H6 J% m. W1 d0 S0 q
80 while (round--) { /* basic cycle start */
' f0 B0 h3 C2 c: e3 }81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
4 ]4 p, _: ~- d3 g7 H4 ]0 \1 d9 G82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
. ~; {/ s" u7 C) ]* M% `5 c' e83 sum -= delta; 0 z! p# |9 }2 A' \$ Q9 j
84 } /* end cycle */ , @9 ~' K8 [2 W& w4 `$ b& Y
85 out[0] = ntoh(y); " z& O' i& M8 i& h
86 out[1] = ntoh(z);
5 [/ j1 a: {8 w87 }2 x- U" ]9 A. N7 n: R4 l
0 x! r, i5 }( b0 k% ?需要说明的是TEA的构造函数:
2 s1 j* v& Z; o. `: NTEA(const byte *key, int round = 32, bool isNetByte = false);
2 b3 f! F5 z: G+ ]1.key - 加密或解密用的128-bit(16byte)密钥。 $ f- \' Y8 N w) s% C( ]" U
2.round - 加密或解密的轮数,常用的有64,32,16。 9 \ {, ^+ x g9 f2 O' K
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
; G( Z$ ^! f" [: Z# e, C5 l- n. n! V2 F/ @. l. x+ B3 W5 W8 Z4 I
最后当然少不了测试代码: |
|