|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" 0 o( q/ W2 a; R1 K* a
2 #include <cstring> //for memcpy,memset
& p* V! b% n/ R8 L- J 3 5 w7 i9 Z1 Q! c0 e: |- T* r1 ~ q
4 using namespace std; ' u& s7 i! F. |1 |
5 9 x& B! g4 G9 y" i4 ?
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
) L6 u, j- `: t8 z7 ? 7 :_round(round)
) W: H* _5 S; v o3 @: }" A0 _9 g" W 8 ,_isNetByte(isNetByte) { 6 w% h' P# i# E* x! G
9 if (key != 0) & [( [& ?% ]: W; @) Z
10 memcpy(_key, key, 16);
6 H) ?$ C2 _/ A" W+ r, D6 c; i11 else
! ~" G6 r3 W9 h. r3 e# S6 ~2 | N12 memset(_key, 0, 16); : T- J& d# j& ^; e9 j6 Z) ]
13 }
7 {4 ~# R/ o7 g3 }$ c! N14 4 ]1 {8 o+ D/ o0 h, Q4 y
15 TEA::TEA(const TEA &rhs)
- q! h: u, X. B" N( ~' [. P) E I16 :_round(rhs._round) 7 ~# |: S& e$ U. H, o M$ N
17 ,_isNetByte(rhs._isNetByte) { ' c J) E3 n" _7 l7 k5 {8 a
18 memcpy(_key, rhs._key, 16); 4 [- m: ?, |+ O U5 K1 U
19 }
) H& K4 P+ j1 c7 ^) r M' y9 ~. L20 2 k9 ~# x; S6 l4 a" c1 g
21 TEA& TEA::operator=(const TEA &rhs) {
* o5 {- d2 j! Q- b22 if (&rhs != this) {
" v; g) r5 b! w: d' G. V23 _round = rhs._round; ) r4 b; K/ _+ [: @ h
24 _isNetByte = rhs._isNetByte; ' l Q! n/ l4 N
25 memcpy(_key, rhs._key, 16); $ k8 Z P/ v. H
26 }
& V7 O; c; ^5 I H# {9 o27 return *this; ' t$ v' I2 K. K' u
28 } 2 r! g/ } ]1 X" B. `
29 ! B: C- m* J' {* v
30 void TEA::encrypt(const byte *in, byte *out) {
. l* H* f" l J- E# c31 encrypt((const ulong*)in, (ulong*)out); 2 j4 T9 n' ]* D1 _+ Y8 h0 G0 M4 ~
32 } 8 l; P* Q+ \5 y. K& a% V8 [
33
0 }( B& g9 Y) r% C" D34 void TEA::decrypt(const byte *in, byte *out) {
' E) y& h% E% S35 decrypt((const ulong*)in, (ulong*)out); ( u1 Q9 e/ k* k' X
36 }
2 D# i0 e6 U3 X, P37
% Y& \+ J1 f# i1 ?38 void TEA::encrypt(const ulong *in, ulong *out) { 6 S& y8 W8 t' [( o
39
0 O9 X% ~- }& K/ Q0 X8 _# K40 ulong *k = (ulong*)_key; ( [) t, r: F) g8 P5 l% j3 e
41 register ulong y = ntoh(in[0]);
G2 k) p/ D) J! w+ Y! ?42 register ulong z = ntoh(in[1]); + O. Z# {/ k, Y6 c+ { E+ }
43 register ulong a = ntoh(k[0]);
8 B! K& w. p/ {( H44 register ulong b = ntoh(k[1]);
; @1 s# v1 Z( w. e8 C! @45 register ulong c = ntoh(k[2]); . Y: H4 \5 [/ H+ ~4 u. B+ Y0 y
46 register ulong d = ntoh(k[3]);
' I. _( e5 u: x6 | q47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
7 F7 J' W: x$ H, @' x! Q48 register int round = _round; / J! r+ \+ g6 E/ q" r
49 register ulong sum = 0;
- E% X# Q6 S/ b) {5 g3 V1 z! b' k50 7 B7 H& X* Z4 I0 L8 O: g" h! v
51 while (round--) { /* basic cycle start */
8 ~* X J. e+ M52 sum += delta; 8 A8 W3 X% v/ h/ w" q
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); - M# O9 v/ N' k) A2 i4 \$ _! L
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); 3 e5 \; O1 b1 L
55 } /* end cycle */
! y4 H- W# l# i9 t) n56 out[0] = ntoh(y);
* ^7 A( _2 ^+ }& p- z/ x' [57 out[1] = ntoh(z); * Q; @4 z& B1 m Y6 o6 L
58 }
# c+ `9 l9 [8 f c Z$ i59
S7 d' w8 i- s8 @2 l# E4 Y, j* S60 void TEA::decrypt(const ulong *in, ulong *out) {
" g0 O; p' N8 A0 j) \7 s" e61 ( R/ y6 X! }& L6 I
62 ulong *k = (ulong*)_key; ; S7 [- H# Y% l; m
63 register ulong y = ntoh(in[0]);
& {, ^# R3 s, A0 x$ k64 register ulong z = ntoh(in[1]); . l* @1 s% P0 D
65 register ulong a = ntoh(k[0]); $ P( |5 n8 c" U2 g; I$ _6 `" [
66 register ulong b = ntoh(k[1]);
0 {, J8 Q( @/ z' `67 register ulong c = ntoh(k[2]); * L w7 {0 ~! Q! ]" B9 p
68 register ulong d = ntoh(k[3]);
; p5 a) Y0 @+ |* X69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 6 z% J5 P- Y) H) D5 u: |/ Y
70 register int round = _round;
9 o# r7 E; y, r3 t/ g71 register ulong sum = 0;
2 t: n2 l+ Z! x72
2 ?( Q; e0 h& ~% k) v73 if (round == 32)
5 M b$ O! [' {* q" s3 J74 sum = 0xC6EF3720; /* delta << 5*/ \+ q ^ {( Q1 f+ u
75 else if (round == 16)
5 y3 {( d8 A. V) e9 G, q+ u76 sum = 0xE3779B90; /* delta << 4*/
+ S7 h. H' x: t0 V) l77 else - w& e# B2 _& Y( j
78 sum = delta << static_cast<int>(logbase(2, round)); 8 D2 f2 a8 ]7 r1 H6 k+ P! z4 X
79
8 z3 ?2 \- R/ I7 n" w( b4 f2 \, J80 while (round--) { /* basic cycle start */
: \$ A1 R/ Z+ C4 x81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); + O( q- j$ d# s. p
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
3 j" K# S6 D" {6 j$ g, E83 sum -= delta; ! M L! O- h2 h
84 } /* end cycle */ + o) a. s) Y9 @- x
85 out[0] = ntoh(y);
" J t* G. D( U$ m* @% x86 out[1] = ntoh(z); : ]& l6 l! a) I; B7 ]$ r' v
87 }( M* l- O# y; C2 a) j; O" Z
# T w* u; T3 U, o9 M1 N4 Z" \1 A
需要说明的是TEA的构造函数: - A L& U9 M/ ?& u5 k5 ?9 d0 x
TEA(const byte *key, int round = 32, bool isNetByte = false); \* n6 A6 p M, K1 z" r
1.key - 加密或解密用的128-bit(16byte)密钥。 ( d/ B: q8 {; \. a- D
2.round - 加密或解密的轮数,常用的有64,32,16。
8 b! K/ r( a. g3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! 7 I, @, q: ?$ E& |; N& C8 U
: T& J2 j9 y; i2 N+ y- R最后当然少不了测试代码: |
|