|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" 5 F5 \1 V R& X0 E+ y
2 #include <cstring> //for memcpy,memset ' p1 ]8 u# H, C& A7 d
3 " O8 Y. z8 B+ v' z
4 using namespace std;
2 w; r! p( u9 q2 X& g: E 5
' b7 m& c5 E/ Y9 o5 c1 O# O 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) $ A+ F/ W" j& T2 b3 k
7 :_round(round) ; L# c N m- X' W5 B C" M
8 ,_isNetByte(isNetByte) {
' t" P; S: }: K6 r, O( _ 9 if (key != 0)
% I* `- X+ K" m2 r9 R10 memcpy(_key, key, 16); . ?! \3 }$ u$ |+ b7 J/ x i5 v" R
11 else
' q6 y2 r# [1 @4 |2 q# k8 y$ v12 memset(_key, 0, 16); v9 p, A* H, I. G3 p0 g
13 }
% j1 V* P4 e! E2 _" p14 9 A* k+ G4 x n. s* {
15 TEA::TEA(const TEA &rhs) ) ^, q0 w7 m2 r
16 :_round(rhs._round) 0 @; q; {/ y3 D' m! U
17 ,_isNetByte(rhs._isNetByte) {
/ D% @/ P. j7 _1 }2 q o18 memcpy(_key, rhs._key, 16);
7 }) _6 @- |: H* O0 F19 }
# H1 T* M% Y2 r20 4 n- u) q: y: i9 [# S
21 TEA& TEA::operator=(const TEA &rhs) { 0 }2 ]! e( b) M
22 if (&rhs != this) { & g0 }/ R- t1 X2 \5 d1 r- |
23 _round = rhs._round;
. _4 W/ ~ X3 h6 D4 ]24 _isNetByte = rhs._isNetByte;
+ A8 v+ r0 G8 O1 w4 }25 memcpy(_key, rhs._key, 16);
' ~- L& N& n9 }! ^3 [" R* M26 }
" O& w# {' ]% c+ `& y0 w4 k27 return *this; ' _. J4 i& F' R2 I
28 } ' y4 k+ G# V8 S
29
! q! m) J5 [3 W; B9 {30 void TEA::encrypt(const byte *in, byte *out) {
& J; u) F8 v2 N* Q7 R31 encrypt((const ulong*)in, (ulong*)out);
/ W! ]9 q: V2 t+ R: C/ X3 o32 } # _' r0 t; l8 \1 {' H
33 4 d9 b- }' y* o8 `+ c( a$ W4 Z# _- j; f
34 void TEA::decrypt(const byte *in, byte *out) {
1 ]# E& ^# f% Y: i9 t' h5 ^8 @35 decrypt((const ulong*)in, (ulong*)out);
- \4 g: B! P8 b* @1 j: |36 }
9 R- z1 L3 o2 q37 + E3 v# D) |1 k
38 void TEA::encrypt(const ulong *in, ulong *out) { , x0 e5 K k1 B7 Z) D" i
39
) m0 Y2 J1 \, R9 o( G40 ulong *k = (ulong*)_key;
' D) h7 O! n! g3 T4 k41 register ulong y = ntoh(in[0]); ; f) I8 {1 X' _7 F
42 register ulong z = ntoh(in[1]);
! G9 I1 T9 a% T% Z- K {9 N43 register ulong a = ntoh(k[0]);
; f' m% T+ N) r44 register ulong b = ntoh(k[1]); 7 j. d8 f ], Y# N! A1 Y
45 register ulong c = ntoh(k[2]); 4 ]6 Y4 `' W2 I; `
46 register ulong d = ntoh(k[3]); 3 L6 n. t! Q p
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
5 o0 e X. x, ?& I3 Z8 X48 register int round = _round; 0 c9 u# Z! `( y& T" [
49 register ulong sum = 0;
6 f/ x) c. G. ~$ B/ I j' W50
; E4 r* H" N9 y% v8 u) B" w51 while (round--) { /* basic cycle start */ $ p1 h3 m1 x* P
52 sum += delta;
4 j* z. u$ y% G4 O' ~6 v53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
2 J5 L% Y* B2 x6 }; _2 }54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); 0 E! Y# p' @; L) I
55 } /* end cycle */
/ Q. V z; b/ ^0 V* e9 Z, T. y56 out[0] = ntoh(y);
) a4 `2 N7 b- L/ Q9 O% Z2 e! _57 out[1] = ntoh(z);
8 v: X$ s9 v! ]. t58 } 7 ^! t, O8 s$ K" F
59
5 q- H8 L: \1 {( L) @( d' S60 void TEA::decrypt(const ulong *in, ulong *out) {
# w7 S ~7 Y7 H _7 e$ q, f61
5 H# s7 x" `0 ~# m, L62 ulong *k = (ulong*)_key;
5 u# G! T* W9 o) |) h. w63 register ulong y = ntoh(in[0]); . @- Y/ ?- C% L0 `# k
64 register ulong z = ntoh(in[1]); ; I& k0 ]$ n/ C9 _' ?/ j1 J
65 register ulong a = ntoh(k[0]); ) d+ e l# c0 M$ d% M6 B& _" n# ?
66 register ulong b = ntoh(k[1]);
# p, M$ j& _% E! j: v67 register ulong c = ntoh(k[2]);
% z" v4 g7 @: B68 register ulong d = ntoh(k[3]);
) v& P! F5 J, L69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
) s1 w% E9 O: b" T% ^/ @70 register int round = _round; ! Y9 T; J. j! o* p/ H
71 register ulong sum = 0; 8 N5 j1 L* _5 G( n& u4 C9 ^4 B
72
0 z3 k2 T( f: Q' [73 if (round == 32) ^8 o1 Z) z+ h3 D$ j
74 sum = 0xC6EF3720; /* delta << 5*/ 5 F+ F* b( y4 h, Z- i2 z C
75 else if (round == 16)
' \ L! H! d# H- J2 B2 j& [76 sum = 0xE3779B90; /* delta << 4*/ 4 g+ i+ c8 M: f4 \/ \1 _
77 else
2 x0 e# R' S; F78 sum = delta << static_cast<int>(logbase(2, round)); 3 n# N3 t0 O" \9 W, y# q
79 ! `% ~4 ^4 O$ [& i5 q3 l: R: n
80 while (round--) { /* basic cycle start */
% B$ u. @* s) m81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
( I( i& l) {- u' g% l! @82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); 9 H' z) S9 S+ b4 e5 E3 \$ n
83 sum -= delta; : C( Z3 b" h3 L( I+ [. w
84 } /* end cycle */ 7 q4 X3 O( w1 l; _
85 out[0] = ntoh(y);
' @, j" N$ X! d# S; r+ `+ \. ^86 out[1] = ntoh(z);
* S7 @) H/ w! H87 }
2 y7 k3 H h, |1 I9 ?% C# Y8 i4 G4 l
需要说明的是TEA的构造函数: + v' C2 g7 p1 | _' Q* p5 ]$ O
TEA(const byte *key, int round = 32, bool isNetByte = false);
$ ^9 d# P: w" K6 A1.key - 加密或解密用的128-bit(16byte)密钥。
6 \. e5 b5 n7 Z0 x( Y6 s- a2.round - 加密或解密的轮数,常用的有64,32,16。
( R# @. G4 T" a3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
& h1 [9 J( k+ B
* K% L4 j) h; e! s最后当然少不了测试代码: |
|