|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
# x1 Y4 D7 \' w- I# x0 @ 2 #include <cstring> //for memcpy,memset
- R- R2 h' u5 Z7 B. r; `+ e 3
5 P9 R6 e3 [: ]+ w8 d 4 using namespace std; 9 I0 r$ r7 b. I$ u) f Z
5
~% R' ?: A R 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
: x1 r; F& f) v! r 7 :_round(round) % d$ p9 M% h+ O/ Z
8 ,_isNetByte(isNetByte) {
, |1 |1 g+ w0 a3 J7 h- I% _ 9 if (key != 0)
# P- Z& o7 p+ ?6 J10 memcpy(_key, key, 16);
H5 ^% V% {1 {2 k5 f) l11 else
" f7 t. L Y* g, \; g7 G12 memset(_key, 0, 16); : t' A3 ]) v( l' w4 {: j
13 } / @: z- J* o* X( s6 ~
14
+ @9 \9 V/ ?& n! l, _$ T! o- ^15 TEA::TEA(const TEA &rhs)
) W \# r) i8 Z; P4 F, r16 :_round(rhs._round) 8 N0 O8 L$ e! B" J% ^0 X+ z0 @1 r! V/ x9 H
17 ,_isNetByte(rhs._isNetByte) { " ^* ]* Z% @: W9 ?: ?+ v' k# y- t
18 memcpy(_key, rhs._key, 16);
7 |' a% c2 |5 U% u19 }
; D4 |$ [1 \2 [; \20 & }7 U% l9 r3 ^2 Y% v M7 |
21 TEA& TEA::operator=(const TEA &rhs) { / U X+ d8 }: u9 `
22 if (&rhs != this) { # h8 q% y& \7 y" \
23 _round = rhs._round;
, s! L3 u* n) w% x g m" C* l24 _isNetByte = rhs._isNetByte;
: W* h" F3 ?( [! B25 memcpy(_key, rhs._key, 16);
& q$ [. @( t- n h, H26 } % B' j2 S! e2 Y
27 return *this; 1 f8 O' s' [ s$ ^3 d# q1 Q3 M# A
28 }
9 p+ e+ @& U+ a) x6 D29
) ~/ i' b( o1 j0 L& ^- H9 b30 void TEA::encrypt(const byte *in, byte *out) {
6 C+ V/ P T* N' j" u8 `6 E31 encrypt((const ulong*)in, (ulong*)out); 4 L f' H! L9 t* W) B4 Q9 {
32 }
# V! t& }- X3 E4 V r! u33 2 f$ v ]* K2 j3 v( m
34 void TEA::decrypt(const byte *in, byte *out) {
$ @, M2 j7 a& h% a% Q: O2 T35 decrypt((const ulong*)in, (ulong*)out); ' C$ U# l. j5 p9 k* c
36 }
6 h* r! \ B" c37
0 }! k4 u% \( x- |, u: H38 void TEA::encrypt(const ulong *in, ulong *out) { / d" X$ L2 U% A4 @
39
) D$ h: V1 `( J+ ^ N40 ulong *k = (ulong*)_key;
7 N% i# d6 \- [- Z$ T# t) H41 register ulong y = ntoh(in[0]); 4 o0 n4 Q L) V& t+ A% E! T
42 register ulong z = ntoh(in[1]);
8 \2 K4 L# _9 ? a43 register ulong a = ntoh(k[0]);
- y9 D5 M: m% s5 f% G) B44 register ulong b = ntoh(k[1]);
3 P9 s% d; _! D/ x$ q45 register ulong c = ntoh(k[2]);
9 S% q& Y: q& d. t1 L# D4 p46 register ulong d = ntoh(k[3]);
& Q8 K8 }, f# }! q47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ " q, E# W$ r' {) k g$ c
48 register int round = _round;
z: b4 } } w4 E. ~49 register ulong sum = 0;
' P6 Z ~6 ]2 f50
& f! y) q' f9 Y! X$ F51 while (round--) { /* basic cycle start */ ' y0 u7 T# a2 Y- N' o2 p3 p; k8 o" W: h
52 sum += delta;
3 X: o, n3 n/ V) B. V53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
( R' C5 f9 Y, k7 e54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); ! l/ U) ?. K) C3 Y0 k0 E- _
55 } /* end cycle */
4 K9 k \) L* }" L56 out[0] = ntoh(y); ) M5 g$ o! B8 l. ?. L% ~" U
57 out[1] = ntoh(z);
: {" i$ v+ D( H2 f8 J: f0 p58 } 9 e% M. r; |$ V/ s# t
59 ( v) `" _0 y! d
60 void TEA::decrypt(const ulong *in, ulong *out) {
- J. j6 M9 C( `% r* b61
' P& T! I' x$ {% M62 ulong *k = (ulong*)_key;
2 [9 t1 c1 z- k( j63 register ulong y = ntoh(in[0]);
7 h8 u, r: s+ H64 register ulong z = ntoh(in[1]);
4 _% n! j: Y% x; C- T8 p5 p8 A65 register ulong a = ntoh(k[0]); ) @! R7 J# v. w) f
66 register ulong b = ntoh(k[1]); - F0 Y# D$ E9 H
67 register ulong c = ntoh(k[2]); 4 E; m* _% `2 Y# {
68 register ulong d = ntoh(k[3]);
) w7 x- y0 @- H1 W* L/ V69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
- H1 K) ^5 C6 `+ [/ q; M& _70 register int round = _round; ' K4 Z; J( m. r3 b
71 register ulong sum = 0;
) Q1 X: e( g2 I+ I72 3 Z6 t! O( A: U* f4 L- z
73 if (round == 32)
. H4 Q% I+ h9 g' r+ X# i5 T74 sum = 0xC6EF3720; /* delta << 5*/ 3 V& D* K4 u6 f$ J5 _9 l0 J
75 else if (round == 16) 6 V6 _6 i# o3 M
76 sum = 0xE3779B90; /* delta << 4*/
5 r5 N5 z+ w% H0 J( x& P& s77 else
; z4 M3 C" x ]* y2 h! W78 sum = delta << static_cast<int>(logbase(2, round)); / L0 P6 a" q7 s! a9 [- ?
79
/ R3 l: z# W. ~0 ~' b) j; T# Z, n80 while (round--) { /* basic cycle start */
7 Q2 e, ^+ K6 F81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
$ O6 L% k! Q4 T0 |82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); 9 G. c4 g, |, o4 L* R; x0 X
83 sum -= delta; ' L) a/ g3 n- y" K& @; S6 p
84 } /* end cycle */
. S# |4 c- d( M2 \& j# o* u( J85 out[0] = ntoh(y); 8 X% l2 C) j" L
86 out[1] = ntoh(z); , x0 p8 @! @% G& m
87 }3 p$ p6 }0 e) h# y
" j4 @8 Q- \# p) E
需要说明的是TEA的构造函数: 2 _: X0 ]) j; b' {* T$ A1 ]
TEA(const byte *key, int round = 32, bool isNetByte = false); 5 w+ U3 f* q. ?$ E a
1.key - 加密或解密用的128-bit(16byte)密钥。 # m1 u6 u/ O, j- w* T% m
2.round - 加密或解密的轮数,常用的有64,32,16。
: N2 `" Q7 \; v- T# Y3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
$ w$ j J) `$ G9 S
. ], H) |) f* C8 V最后当然少不了测试代码: |
|