|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" 0 o! c( a. k$ E2 A& m
2 #include <cstring> //for memcpy,memset
. f. ^0 u# a0 Y0 o) Z 3 6 [& c% u/ }& N% z
4 using namespace std;
7 O3 m! h' u& a 5 ) [- e2 e( c1 L( k3 Z+ E
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
5 w m) g. w& {) a0 B8 x 7 :_round(round) - T6 G2 ?$ G% a8 k% g+ i
8 ,_isNetByte(isNetByte) { ' f& @: {7 N) h. E$ e
9 if (key != 0)
5 i, @; h+ x8 {; G# `$ K10 memcpy(_key, key, 16);
7 i' |4 I! ]; w; a+ v3 {6 R11 else
0 t s" p% k' i+ H9 {$ m12 memset(_key, 0, 16);
% N3 _" z/ ]. Z4 B# i) \1 u13 } * P+ S. D, t1 Q0 u
14
9 [( e) N' q6 I+ W15 TEA::TEA(const TEA &rhs) % j% k! H$ k# C+ I! D/ d
16 :_round(rhs._round) ! Z+ }4 k# ]/ l
17 ,_isNetByte(rhs._isNetByte) { - F! t4 Y. j* z/ D
18 memcpy(_key, rhs._key, 16);
- v6 U) ~( O u; q- Y3 k" z19 }
# [# b; [; Y4 w" }/ g+ ]. M20
- e! W( T( K5 |" r" Z9 Y( e. u21 TEA& TEA::operator=(const TEA &rhs) {
! U/ W1 E# m2 |* s) b9 T22 if (&rhs != this) {
% Y$ d7 M! F) N# S5 x2 T23 _round = rhs._round;
( m- b4 ^% h$ \2 ~" Z$ C, z24 _isNetByte = rhs._isNetByte; : t6 a( _& u$ `' d: T6 L
25 memcpy(_key, rhs._key, 16);
* i' p; V$ X& J2 t- w' \26 }
* G `! X- t% d% h( S, }9 s2 O0 L' @& |27 return *this;
' N: r4 @7 j4 E. s9 m' c28 }
$ y8 l! E. `! k# ]* @; U29 ; n" C5 ^1 |8 D2 ?" H+ T
30 void TEA::encrypt(const byte *in, byte *out) {
5 B/ X: H+ q8 [* O3 w; U1 ~; _: P) i31 encrypt((const ulong*)in, (ulong*)out);
+ J4 w0 P8 F: \32 } / e; r! U# @( [2 w, Z
33
( N* E: g6 t. R2 ~8 }! {34 void TEA::decrypt(const byte *in, byte *out) { 0 d1 p M$ B$ ]1 N5 L9 u
35 decrypt((const ulong*)in, (ulong*)out); 5 K* @4 G2 p6 P2 B$ i. F. u
36 } + B; m4 _: V) k2 [: I
37
: H: d* j" x/ d! X! {9 }38 void TEA::encrypt(const ulong *in, ulong *out) {
- S) I' i: G3 H. y39
5 K( a0 h# @, g, V; L/ g40 ulong *k = (ulong*)_key;
9 y5 ?% ^, S* y2 k41 register ulong y = ntoh(in[0]); ' p' |4 Q; V" [% k3 E
42 register ulong z = ntoh(in[1]);
, l, p$ E) {* p4 Z' h43 register ulong a = ntoh(k[0]);
4 s$ @% E( S$ v: n y9 \! w: ?4 g7 l44 register ulong b = ntoh(k[1]); ( u0 t5 w0 U6 |* g0 {
45 register ulong c = ntoh(k[2]);
! b5 F1 d3 J. r1 P46 register ulong d = ntoh(k[3]);
6 s) M( S5 d2 c9 x \7 I4 h& g47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
7 g* J3 X0 p2 F o& ~! }+ [48 register int round = _round; # D1 Q o; w7 E" g0 E
49 register ulong sum = 0;
* T/ Q( G. E( g0 ~9 n6 K50 ) l2 {" O) A2 l v O: R. \* h. |" p
51 while (round--) { /* basic cycle start */
' v% [" c8 U5 q$ M5 X$ s! H) t9 O52 sum += delta; . b# S1 T2 e3 u& O Q
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); 5 d7 ]5 o) C. `
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); 9 } P1 T; t+ b4 V
55 } /* end cycle */
: a* B3 R$ k1 q! }/ F9 p- y9 P56 out[0] = ntoh(y);
8 ?5 v! e* R- k57 out[1] = ntoh(z); " @1 u# ^- J/ G; \# d% o
58 } / N2 {( Y; C1 [( {* {
59 % e# J& M" B. e* L8 \2 y
60 void TEA::decrypt(const ulong *in, ulong *out) {
& K; A$ O; S5 \5 S) K M+ o) \3 U' F61 : w) K4 S0 S" r5 s* X' ^
62 ulong *k = (ulong*)_key; : Z9 k0 g; j$ V
63 register ulong y = ntoh(in[0]);
- \8 f6 O( u) S2 {8 S9 y% A64 register ulong z = ntoh(in[1]); % d0 ]( o" m* w# b: e
65 register ulong a = ntoh(k[0]);
$ l3 L5 \+ U1 y8 U7 S/ y$ ]( `66 register ulong b = ntoh(k[1]);
' \1 b& \* ]5 t" G67 register ulong c = ntoh(k[2]);
3 X# G, V7 ^% x, F68 register ulong d = ntoh(k[3]); # B5 Q0 t" o5 G4 c. G
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 7 x( K/ \) P/ w0 k$ P0 M8 L
70 register int round = _round; ' ~0 p" }4 o, l
71 register ulong sum = 0;
* z! d; P! K+ J+ Z3 V. Y72 * M% x$ D" D; U
73 if (round == 32) $ W# a0 x, v5 x2 c+ |1 g' ?
74 sum = 0xC6EF3720; /* delta << 5*/
! H# r% D' Q% g7 w75 else if (round == 16) , `3 Y6 v* b4 t* Z6 p& w
76 sum = 0xE3779B90; /* delta << 4*/
' p- G d( M! m# C* t77 else 6 R4 T3 c& q) G& Q# U% n2 C
78 sum = delta << static_cast<int>(logbase(2, round));
/ I; _+ e# Z0 W5 H79 6 i. N* e" H' g6 c$ L' V: M$ \
80 while (round--) { /* basic cycle start */ + o5 t0 D i p1 Z" Z' D$ f8 ~! m
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); 8 x$ C% p7 C% [! P( d1 H: I
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
8 m, Q* I- r2 `% Q, E+ i' n: l1 G3 W83 sum -= delta; 2 c7 l: S% [, f/ [
84 } /* end cycle */
" d0 j% ?9 r6 S" j" ~) T8 |$ ]85 out[0] = ntoh(y);
s, A$ W% w, `" E }. g86 out[1] = ntoh(z);
* u0 j9 Q/ U: x j, G- Y87 }
2 l* X8 a7 R" W# j
3 h* ^% @3 r1 J7 _% b' n- [需要说明的是TEA的构造函数: % R/ h) T, h/ }1 q5 ]* V& C- A" q
TEA(const byte *key, int round = 32, bool isNetByte = false); ( W5 |$ [& a8 p0 t: n3 o% V
1.key - 加密或解密用的128-bit(16byte)密钥。
$ \8 {' K* y7 J2.round - 加密或解密的轮数,常用的有64,32,16。 % I j, v* x- b, y" l0 M. K
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
, }- g+ h- c! o6 W8 F- h* X3 S+ |3 ?. s3 O, R
最后当然少不了测试代码: |
|