|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
6 V6 P! g3 |4 c1 j; G 2 #include <cstring> //for memcpy,memset & u1 x) l1 ?- m/ g8 D1 ~
3
( g' j: }' y. k) ] 4 using namespace std; 8 n8 U# I2 g% J. {3 x% N6 u6 f
5 * m% R7 \- O/ Y4 Y7 c
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) 6 q" _( |6 ~! i9 \: _
7 :_round(round)
& s1 E3 L' ? \$ ^ 8 ,_isNetByte(isNetByte) { 8 ~3 o) Y6 G( a7 N' |
9 if (key != 0) 6 {/ }6 d; @1 N; r9 |7 T3 L+ v
10 memcpy(_key, key, 16); 2 f6 R6 x' R' D4 V5 Z& ]
11 else
7 F% s6 t, \6 Y6 d* ~1 z12 memset(_key, 0, 16); , `/ m F0 N X- p
13 }
2 D8 i7 M. }: ?5 y& s14
( ?8 L6 J2 L6 v; }# o+ s15 TEA::TEA(const TEA &rhs) " d2 @& T4 k2 m4 |6 V; h; }3 R
16 :_round(rhs._round)
- [, q1 K: b) R% l! b& E; w5 N( }17 ,_isNetByte(rhs._isNetByte) {
% u2 }. Q3 M6 ]18 memcpy(_key, rhs._key, 16); $ j- U" o0 m9 W! u* M$ L9 n
19 } . g0 i6 E8 z9 N+ v/ t
20 7 G5 N+ O1 X4 `4 _5 X0 S
21 TEA& TEA::operator=(const TEA &rhs) {
9 h- F' y9 I4 A2 K22 if (&rhs != this) {
5 p0 x. w# ^4 g5 a23 _round = rhs._round; & ]3 J# d% S7 l2 b# u
24 _isNetByte = rhs._isNetByte;
5 a% V+ u" [+ }2 k" T25 memcpy(_key, rhs._key, 16);
1 j% }* \' [3 l3 v5 s2 n& y26 }
M9 X9 j- u5 Z. z27 return *this; / {% }) H9 Z: d. {& y
28 }
4 ?3 j) L0 n0 ~& ^5 V1 A/ x- S29 1 b5 }! J3 |8 B3 ]# s
30 void TEA::encrypt(const byte *in, byte *out) { 9 q2 V. M! f8 E$ p: n
31 encrypt((const ulong*)in, (ulong*)out);
# J: d9 d; B, O3 M5 L% e2 Q32 } 6 E/ u' J. O" I5 E5 U2 w
33
, T- Q, O. [, O: c4 D+ S7 g34 void TEA::decrypt(const byte *in, byte *out) {
3 |/ L, o" K: k35 decrypt((const ulong*)in, (ulong*)out);
- A9 n& @' D' ]0 B+ u T* \36 }
2 ?( O8 r6 r2 {. K" H37 & l- d' g+ U# w7 H. i
38 void TEA::encrypt(const ulong *in, ulong *out) { 2 C, y) H2 y. G! V/ h- P- C
39
+ T4 g- o# s' j+ _40 ulong *k = (ulong*)_key;
5 d* | |/ _$ _ u) ^6 F% C41 register ulong y = ntoh(in[0]); + a& a0 @# c4 J; n$ H2 s
42 register ulong z = ntoh(in[1]);
4 M& `" z0 u+ q5 y( a43 register ulong a = ntoh(k[0]);
6 O! ^: J3 W7 F! h1 m; e4 u: K1 J44 register ulong b = ntoh(k[1]);
, P% `& J* S3 y) o; V45 register ulong c = ntoh(k[2]); $ R0 c7 Y/ }! I% F! K& X4 {
46 register ulong d = ntoh(k[3]);
% m3 K% z, Q- [4 h47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ / V2 A" [/ V7 [+ x; C
48 register int round = _round;
& V/ E9 o1 q% r49 register ulong sum = 0;
* ^7 ^/ m" m+ X50 - a$ z8 L* U2 F
51 while (round--) { /* basic cycle start */
& u$ J0 n2 B# w8 Q5 e6 `52 sum += delta; ! R' d6 h8 b/ t2 ]7 x4 j
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
3 @/ w7 ?9 I: [$ m* W* M54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); + \; M- `) ?; B2 {% t( [$ a
55 } /* end cycle */
i9 D) r# x$ n- r" ~( R56 out[0] = ntoh(y);
! L, W! n% `6 g1 }9 h4 |1 z: L57 out[1] = ntoh(z);
: N n0 I4 a) }58 }
/ X9 M& [ o# e9 f59
' r" y& J3 B3 k+ s0 b60 void TEA::decrypt(const ulong *in, ulong *out) {
! C$ [2 ] M( j* [61 3 f& F2 y' }3 \* q. }1 {1 }
62 ulong *k = (ulong*)_key;
. J! ~1 x: q& ]* `63 register ulong y = ntoh(in[0]); & F% j z+ E3 U/ j: m' g# U3 g* _
64 register ulong z = ntoh(in[1]);
; H2 P9 s: T$ T65 register ulong a = ntoh(k[0]); ; h: b/ |* c8 ^! d% k; v- o
66 register ulong b = ntoh(k[1]); 6 k( @) f4 E+ G9 [; d r
67 register ulong c = ntoh(k[2]); 5 S1 z: Q4 A$ v Z1 i0 b' h
68 register ulong d = ntoh(k[3]); 7 N1 A5 B1 p0 s) C j' r- g
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 0 z# I6 g6 Y7 F- ]7 H5 t d: S" Z
70 register int round = _round;
# |& P+ d+ s9 `' F) Q71 register ulong sum = 0; 4 M% Z2 n* x$ _0 S8 L
72 & W; L( _& S) [& S
73 if (round == 32)
3 K1 N! Y, Z; @0 J L; Y& V74 sum = 0xC6EF3720; /* delta << 5*/
" l) j- u4 m) ?$ \' a75 else if (round == 16)
- H# L4 ~8 K, ?5 w; Q' O% H76 sum = 0xE3779B90; /* delta << 4*/
' t7 v) |: u, K, R$ u& R77 else
; A; \. P2 M7 l! @" p6 o4 _78 sum = delta << static_cast<int>(logbase(2, round)); 3 [1 n$ F- g* r( W" X' @
79
+ j. w7 n( q l& H" n9 Q% H80 while (round--) { /* basic cycle start */
5 `9 \6 F; a3 f! m6 d2 N! z% c6 U4 A81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
5 d" V& {3 n: i. s& P% s3 O4 w82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
m y% j" ~, H3 k. R9 ?83 sum -= delta;
/ z) ~. X6 k0 I& ^! I) D1 \+ Z$ u9 A84 } /* end cycle */ & K7 |4 a9 d2 X0 @; U% v
85 out[0] = ntoh(y); * R. Z" I( e& r, O8 y2 J+ A' @2 j
86 out[1] = ntoh(z);
W/ x6 h0 Y" Z' [7 C S; g87 }
% b6 ^+ I, c3 T/ Z+ r v
- @4 f7 @* a# U$ e2 `" ~2 [) U需要说明的是TEA的构造函数:
) a! z# C/ R: n, d4 e oTEA(const byte *key, int round = 32, bool isNetByte = false);
% T! `1 p0 Z5 w2 q1.key - 加密或解密用的128-bit(16byte)密钥。 N* {* ]/ j5 n) F* E7 t
2.round - 加密或解密的轮数,常用的有64,32,16。 7 x, r) ~2 m6 r* L+ q
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! 8 C+ |6 \$ m0 ]! P; N
; T1 I, A6 Y5 z. t" A, @4 x# q最后当然少不了测试代码: |
|