|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" ' A+ R& A; b. j: k$ M; k
2 #include <cstring> //for memcpy,memset
0 j/ v9 W' s" E 3 % E) o8 s3 o3 H( z) x
4 using namespace std;
1 p* Z% j+ L* f7 i7 ~6 a D 5 # a7 R! F- ] {" X
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) # k$ [& [/ O- e- G+ [; P
7 :_round(round) ; O, T- l) x8 n- k. {. X8 k
8 ,_isNetByte(isNetByte) { 6 y" p1 t! K Y' ]% `) @: e
9 if (key != 0)
+ n5 | R) T& G$ o/ P @10 memcpy(_key, key, 16);
9 a, X9 h. K# _. W; c9 z8 ~11 else
+ S0 R9 b2 [+ a+ {12 memset(_key, 0, 16);
& ^% L9 S3 k G) G- A% S13 } 5 ^' d* b) b+ f5 `' Z
14
$ w+ z3 I7 B/ o8 t15 TEA::TEA(const TEA &rhs) 7 w9 n2 s* h1 D9 b
16 :_round(rhs._round) : R; {9 S# n/ N7 X3 l: h. ?7 z
17 ,_isNetByte(rhs._isNetByte) { 6 Q! H/ W( n1 v, [
18 memcpy(_key, rhs._key, 16); : z' [+ B/ }, ?( M/ I$ B
19 }
8 g% a6 R+ M' {2 L20
4 e9 g5 T2 G9 t. H' D( N21 TEA& TEA::operator=(const TEA &rhs) {
; y& Y6 N; ~7 c: W* Q1 I3 g/ |22 if (&rhs != this) { 6 R$ E& t( g* Y6 i. [- L) e; R L
23 _round = rhs._round; ) Y/ @3 k3 X- U
24 _isNetByte = rhs._isNetByte; T5 ]4 ^& G' t
25 memcpy(_key, rhs._key, 16);
* J: B5 C& m% I- E4 X. f3 \26 }
7 C- E$ h B r27 return *this; 1 W' H+ A2 G |* u: F5 |+ A
28 } + o; U2 M/ G' M/ g7 X5 _+ w
29 5 s- C& B; q3 X9 Z! P
30 void TEA::encrypt(const byte *in, byte *out) { ) J) _9 x5 s4 f6 Q- k
31 encrypt((const ulong*)in, (ulong*)out);
9 T, `0 L) B Q4 @! P$ z32 }
2 i" n6 m/ g4 }* y33
- R8 I# M& Q8 r$ C34 void TEA::decrypt(const byte *in, byte *out) { / q% Y1 o- J* |5 S
35 decrypt((const ulong*)in, (ulong*)out);
h! \' `' B# I5 a2 F36 }
, }* P' a+ s6 k5 p0 u0 S/ K' |37 1 \4 G: x7 e5 i9 X$ j/ `
38 void TEA::encrypt(const ulong *in, ulong *out) { # {( A, n$ B# Q2 I! ]
39
( a1 k" d9 `7 U- B40 ulong *k = (ulong*)_key;
$ \+ i5 E- I# k! |41 register ulong y = ntoh(in[0]);
1 U0 j& u- p+ s7 K! X, W% t42 register ulong z = ntoh(in[1]);
5 }8 q0 W& n) ~43 register ulong a = ntoh(k[0]); / D' V- }" d! {$ }8 x2 j" L2 a
44 register ulong b = ntoh(k[1]);
7 J- {1 s" K4 V45 register ulong c = ntoh(k[2]); 3 V' Y' ^/ {9 J
46 register ulong d = ntoh(k[3]);
, n5 @" d5 N2 J, i47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ $ P# u$ C. Q: F) Q0 o. d
48 register int round = _round;
! P J* k, b8 U) W! [49 register ulong sum = 0; " w9 p9 g6 d. K8 Z! b% v
50
; I# q' M5 Y- {51 while (round--) { /* basic cycle start */
" I/ u* [" v* t% \, M52 sum += delta;
# H8 C$ q$ _ Q# b3 E53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
: j5 G% C, H* n4 |54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); ! l, {5 R2 A' H2 H5 v1 Z8 R
55 } /* end cycle */ 8 U6 K# G) z, b# b4 T: V. A# C
56 out[0] = ntoh(y);
7 @4 K0 { A( B$ S57 out[1] = ntoh(z);
5 i# p/ A4 k5 z7 \6 T$ w58 } * p& g( G+ n+ E. m5 X
59 ( |! s8 b- k3 c+ A
60 void TEA::decrypt(const ulong *in, ulong *out) {
! p' B0 k1 b$ {# A+ ?3 N! F# U61 5 X# e0 g9 |0 B6 {# {# K
62 ulong *k = (ulong*)_key; 5 _" e& u# P8 |; H% U1 Z8 E
63 register ulong y = ntoh(in[0]);
. l( B! t& K3 t% Q! m+ W1 m1 i64 register ulong z = ntoh(in[1]);
3 R) U- s/ J6 q$ F* |+ j7 ~65 register ulong a = ntoh(k[0]); % n- ~8 Z- S% j3 \: r" ] x" R% J
66 register ulong b = ntoh(k[1]);
& q' [8 R: K5 O' ]* x6 @3 m67 register ulong c = ntoh(k[2]); : B3 f, ~! \( E2 q
68 register ulong d = ntoh(k[3]); 0 k; n/ {6 ?4 |) \9 G
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
7 z3 A) e' B# e$ d h70 register int round = _round;
2 S; j4 F' M& D, n( T& u- O5 o71 register ulong sum = 0; 5 h- O# f1 v1 _9 R
72 6 B) m( ~. g8 O; J" }( Z) w
73 if (round == 32) 9 U% s0 ~( W- x9 f- N4 J5 F
74 sum = 0xC6EF3720; /* delta << 5*/
% V5 O& x( A {( K* L& F/ ]75 else if (round == 16)
9 x4 {; Z6 V- q) A76 sum = 0xE3779B90; /* delta << 4*/ ( j; M) ~: z/ U$ A: @4 ?
77 else ; X- i3 w" }; O) J6 d) v. v
78 sum = delta << static_cast<int>(logbase(2, round)); $ K$ J2 z; {: l# {/ A/ O: J* t/ n# g
79 * |& ~, a2 L# {: \
80 while (round--) { /* basic cycle start */ 3 x# z7 I4 X6 p7 B! E( `; M
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); 6 e, B h* K8 U" d5 W+ ~
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); 8 ?" u2 W/ r7 C: o, a
83 sum -= delta; - G6 Y& l: Y' n* M' o
84 } /* end cycle */ : j: E* C4 M8 B& `0 P
85 out[0] = ntoh(y); 2 W# w' t7 I' j
86 out[1] = ntoh(z); . n5 V' J% M) g0 [' b1 v
87 }
, S! R( e8 z! C* {: }5 G
7 Q% U8 ]7 [3 X6 V w4 i* m. z需要说明的是TEA的构造函数: 0 o3 K: i- \ H; H' ]( |* q4 k
TEA(const byte *key, int round = 32, bool isNetByte = false);
2 L( H* Q: m- l" C& R9 ~+ N4 t1.key - 加密或解密用的128-bit(16byte)密钥。
; O5 b& M. n8 n0 r0 p) T5 y2.round - 加密或解密的轮数,常用的有64,32,16。
: H2 i" j4 ]- G1 J5 K5 a2 D U: I9 T3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! 1 [$ t& }1 k- m
( M' D, |% g+ e最后当然少不了测试代码: |
|