|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" # s0 v7 R2 z8 |- ^* }
2 #include <cstring> //for memcpy,memset
( E; r0 _: T2 B6 H/ b 3 4 I8 ~ t1 R9 x; w( w
4 using namespace std;
, y# F# A5 O+ p8 ?5 Q( N 5
6 ^& K/ G9 B) j; P# a 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) # s, u' l) z6 J/ Y9 t7 H
7 :_round(round) : h/ @' m9 k& R% i/ s7 h7 D
8 ,_isNetByte(isNetByte) { 0 t! {% c1 b2 F6 T! V! f
9 if (key != 0)
+ J1 I0 e( p' B6 c9 L0 m3 P10 memcpy(_key, key, 16);
0 |+ h2 b1 }5 o$ \- u( b11 else
f# U3 D1 ^. B2 `- [* J12 memset(_key, 0, 16);
7 o, g3 W- Y4 H% T- j13 }
7 K! N1 [5 X& n8 W+ @0 f" H14
/ q" d/ n3 d# E5 Y# h3 ~. f" T! T15 TEA::TEA(const TEA &rhs)
1 x4 L( J2 `" Z# ^% y$ f/ C16 :_round(rhs._round)
% r$ l; |0 s& l17 ,_isNetByte(rhs._isNetByte) {
* f" u3 C; v0 ~ d3 R0 }) G18 memcpy(_key, rhs._key, 16); ( l# l- X; P4 l; C0 d$ \- V
19 }
, A0 \8 l3 \( J3 b& k# F6 z20 8 v$ `1 a4 Z* T& V+ w- N' K8 p N1 h+ H
21 TEA& TEA::operator=(const TEA &rhs) {
! Q# Z5 j5 X$ Q: A22 if (&rhs != this) { ; ~7 r4 P- H; P+ R
23 _round = rhs._round;
9 h! a& u( j% y* `* U& F24 _isNetByte = rhs._isNetByte;
, ~: Y0 i: G) s25 memcpy(_key, rhs._key, 16);
6 E8 w4 U' m3 y3 M0 H5 P: J- q26 }
" k3 ?$ }# G! T/ _0 o27 return *this; ) m! {. \4 U) _' R, h* n. G) p! x# K
28 }
* C0 r7 \/ E6 ^# ?29 $ e0 \0 q9 [" X! V& d4 [
30 void TEA::encrypt(const byte *in, byte *out) { - u( Y1 O) K- W; R
31 encrypt((const ulong*)in, (ulong*)out); ! T, m' V6 Z5 W) h) C8 h/ z
32 }
& s" \" I& y( U2 i33
$ f5 m0 Z. D* N- }+ k: ] Q34 void TEA::decrypt(const byte *in, byte *out) {
5 B) ]& {3 C! |2 O. x7 n. U3 V35 decrypt((const ulong*)in, (ulong*)out); # h) B! T0 v9 `- o
36 } . _& }# X; e9 M0 E. g5 I! w* e
37
# q( g3 Q( s! }1 ?38 void TEA::encrypt(const ulong *in, ulong *out) { h" `7 [8 X# C
39
" `; j' ?3 m% C+ d* S q+ Z9 M40 ulong *k = (ulong*)_key; 9 e% C' d- o/ ?( D, d+ i" o& b
41 register ulong y = ntoh(in[0]);
, P* j! h. d: } b- X+ G, j: r42 register ulong z = ntoh(in[1]); - B' f$ v, e& F. z3 R- S# A2 A1 T5 a
43 register ulong a = ntoh(k[0]);
$ h5 e8 n& C/ ?4 X! }44 register ulong b = ntoh(k[1]);
. @- r: Z; v+ k) i, P: {45 register ulong c = ntoh(k[2]);
9 o+ H% F) @+ x; q6 x8 f/ |46 register ulong d = ntoh(k[3]);
5 H9 I6 j# \; j: A4 i) n ^47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ ' Y- H4 q# M! }
48 register int round = _round; % k8 W' j9 m# q( i/ G+ E+ q
49 register ulong sum = 0; : s0 _ j) ]! l# X
50 h6 ?7 m9 t! Q, }$ b5 H! j
51 while (round--) { /* basic cycle start */
# k" i7 v( l$ ~* R' v3 t2 B52 sum += delta; : c5 R9 i) p/ Z% P7 N
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); : s% J. \* s+ a+ Y# ^8 _
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); O0 ]! T9 Q) D% H4 M1 v1 g; u
55 } /* end cycle */
4 t7 C% Q, M0 i* H56 out[0] = ntoh(y); . Y. |! P, {) D( F& v
57 out[1] = ntoh(z);
2 o M6 a; M( r6 p58 } " g% a. [( H% H$ x2 c& T( O, R/ |) U
59
5 [0 v9 {- H3 y0 s4 c. _. o60 void TEA::decrypt(const ulong *in, ulong *out) {
: U7 q* s3 v9 \. B61 E) I, e' n& f+ `
62 ulong *k = (ulong*)_key; 8 \/ Q0 S6 o& H& _) _9 k) K3 w
63 register ulong y = ntoh(in[0]);
. U; n. w! _" ^$ }! t8 }64 register ulong z = ntoh(in[1]);
) j) U- }% g, g9 ]9 Z65 register ulong a = ntoh(k[0]); , Q7 a% c6 S0 M& ]
66 register ulong b = ntoh(k[1]); 0 w! f7 e. l8 X
67 register ulong c = ntoh(k[2]);
! w7 U1 \ A: n. ~9 ~) s; [68 register ulong d = ntoh(k[3]);
$ F/ Q1 c M: w4 q) e69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 5 L( F1 P: g6 T$ ^
70 register int round = _round; 0 P+ h' A( r* U. D
71 register ulong sum = 0;
' R8 D% M7 s# M" J& l+ _& P0 x72
/ Z/ V3 H4 V5 @$ D+ h73 if (round == 32)
; f, _& B+ I% y6 |; h74 sum = 0xC6EF3720; /* delta << 5*/ 4 l) L2 T) k9 w1 Y3 p+ S \
75 else if (round == 16)
( n4 T1 t& h3 ?& c2 N. C76 sum = 0xE3779B90; /* delta << 4*/ . K1 @' E" I3 ?# D0 L5 G
77 else / H4 t* r7 o2 {& W4 _
78 sum = delta << static_cast<int>(logbase(2, round)); 9 Z' Q @! {: B1 k, z& F" [7 @
79
) m( v! z) \ R( E7 M; @80 while (round--) { /* basic cycle start */
5 j6 ~3 f6 d7 y81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
: ^2 U" [. B+ ]) I& I! M( B82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); % Y9 W" s% S- a7 M3 k# n& j% x
83 sum -= delta;
, q9 j' q) j: {/ @2 ^2 V9 j84 } /* end cycle */ - {) Y; G1 F3 ?' k! X8 F. h
85 out[0] = ntoh(y);
8 }+ k( `# f0 O86 out[1] = ntoh(z); 3 t2 W9 D ?. E
87 }
9 j4 m' Z ^! G7 X. T1 Q# O
$ L7 f& R; }6 W- P需要说明的是TEA的构造函数:
- x7 _' A$ T; PTEA(const byte *key, int round = 32, bool isNetByte = false);
) A' q x- }/ e2 N! s1.key - 加密或解密用的128-bit(16byte)密钥。 # Z9 u f/ w+ Z X7 X
2.round - 加密或解密的轮数,常用的有64,32,16。 ' T# T7 A2 U; P7 Y/ D
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! " ?( N# N! J+ Q; p
( T5 c" y$ C- t: b5 c) i
最后当然少不了测试代码: |
|