|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" # G" L; e7 I, C; A8 W, f: w' L
2 #include <cstring> //for memcpy,memset 9 e) x8 f. X8 W
3 3 a: O5 }1 O" u5 s
4 using namespace std;
. W: g( q. J; Q q9 j. ` 5
3 d v4 t4 h) j$ k 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
: c( y7 M$ u- s/ @ 7 :_round(round)
' ]1 M; R. i& q8 y* y 8 ,_isNetByte(isNetByte) {
" ^# T! w7 e' j+ P 9 if (key != 0)
1 \& O. l' X/ g* q; K6 f10 memcpy(_key, key, 16); & p9 H2 ?6 ?( y$ a6 v
11 else " t2 W. y( D; @8 t# f; K# e, w* \
12 memset(_key, 0, 16); 2 C }7 S2 B7 {4 x
13 }
% N+ L0 ?3 l+ J$ q! Q' j9 [& S8 h14 2 J9 O" K2 J- N2 l1 J5 t
15 TEA::TEA(const TEA &rhs)
6 P: d4 R! A, f7 ^& x: v& B16 :_round(rhs._round)
' J1 N1 R \& W& A: w17 ,_isNetByte(rhs._isNetByte) { ) y; H8 M' v# @0 ?" O7 c. }- N
18 memcpy(_key, rhs._key, 16);
) O$ p7 m* n$ ~$ ^; z19 } , V- h" L _& b" x7 n3 q. W
20
! t7 z& Q# |+ u, B) e21 TEA& TEA::operator=(const TEA &rhs) { 2 w1 U% W# H1 k& c/ a
22 if (&rhs != this) { 7 X) C# A* d: Y" f8 n& Y
23 _round = rhs._round;
# } S- m# s& m24 _isNetByte = rhs._isNetByte;
. }' L4 _0 d/ ^; \25 memcpy(_key, rhs._key, 16); ) e+ V7 z3 ]- J/ y
26 }
9 O9 ?1 e6 Z S27 return *this;
$ D: D' {/ L5 E+ w. e9 Z28 }
6 u% `" E- x- Z4 S9 n29
2 ?; Y& l9 R$ b4 M$ ^30 void TEA::encrypt(const byte *in, byte *out) { 9 s! w& h* F4 W7 E7 N3 y4 U
31 encrypt((const ulong*)in, (ulong*)out);
* J. | J. J. X# I3 X2 m32 } . j! }# ^0 m& P) K9 E E
33
- |9 s) y: D3 a* R) ]' @. V34 void TEA::decrypt(const byte *in, byte *out) {
% J) f/ s3 D4 b8 {# A: {8 O35 decrypt((const ulong*)in, (ulong*)out);
8 |5 w4 C5 ~+ p8 i+ t36 } ; v* L# O% K, D1 j6 c5 H
37
- X; k+ S& r- r$ k! w i) y38 void TEA::encrypt(const ulong *in, ulong *out) {
5 K0 i/ N$ L# I, ~: W' ?, t39 ' \( p& ~& o, ~* l- \
40 ulong *k = (ulong*)_key;
$ a4 N( a5 m( q; K' _* J& i% Z% C41 register ulong y = ntoh(in[0]); 4 J; ?7 N# r; c" O6 {6 y4 w
42 register ulong z = ntoh(in[1]); 7 @) [3 a8 Y: i( B# X% C7 m$ s
43 register ulong a = ntoh(k[0]);
- v5 m. v/ T* `6 V8 d9 _# W1 B44 register ulong b = ntoh(k[1]);
: M; K' Q) K: E4 G& B45 register ulong c = ntoh(k[2]);
1 R& H: u: G! @. {' r46 register ulong d = ntoh(k[3]);
( ` K" A: b0 {7 C) r! K- p47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
; T- ]: |$ E3 @" @6 u48 register int round = _round; + ^7 u4 I" h7 Y$ a
49 register ulong sum = 0;
7 Y N4 E$ ~/ q+ J( t" u7 {: z8 F50 2 ?/ ^2 Y/ \% `7 y
51 while (round--) { /* basic cycle start */
b+ |5 R! }! `! C3 S# \( P52 sum += delta; $ J2 `3 ?4 o! B* O, a$ ?) R
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); & t7 s$ H8 z( E" ], b
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
7 U9 s8 n7 t2 f4 U55 } /* end cycle */
/ ]' v1 l+ d3 d0 m1 N. a56 out[0] = ntoh(y); 5 C* D5 t3 J- p& G. d! Q
57 out[1] = ntoh(z); 6 g; N! J+ C" L7 k4 f
58 } 8 _/ @( Y0 d R1 s
59
: ?% F7 M3 ~7 P( T1 a60 void TEA::decrypt(const ulong *in, ulong *out) {
( n) {/ d& k, x9 A9 T t/ L61 ( p; C: o2 j w, e: {- @" @
62 ulong *k = (ulong*)_key; 8 J) F( g9 s7 H# [4 s. u! I+ g
63 register ulong y = ntoh(in[0]);
" R* @$ O8 k* g! V: t; {64 register ulong z = ntoh(in[1]); 4 A& E4 s! I1 q# m" V
65 register ulong a = ntoh(k[0]); 0 Z5 \3 g( A" D' x4 ^: g
66 register ulong b = ntoh(k[1]); ; ^: G( |6 t$ \# u. C
67 register ulong c = ntoh(k[2]);
' _' h* e( p* T* T! u8 q68 register ulong d = ntoh(k[3]);
9 V: U$ O& o( Z& |* o5 p4 U6 L- j69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
h* i: S+ I) q, A. p70 register int round = _round; ! |$ r1 @6 t: Q: j/ x
71 register ulong sum = 0;
! z/ L) o# N; ~7 ^72 / X6 q' p' H! h1 F y Q5 i$ f
73 if (round == 32)
' q- P& x! Y/ e. [+ D, g- c74 sum = 0xC6EF3720; /* delta << 5*/
% _* `! z+ Q+ Q; d2 M9 r75 else if (round == 16)
$ e- x5 c# F- |76 sum = 0xE3779B90; /* delta << 4*/ ; X7 A: Q E( D' {+ R8 N3 K
77 else & v7 G3 t0 K* v' v" Q& H6 r
78 sum = delta << static_cast<int>(logbase(2, round)); 0 Q6 X- S: X/ O
79
5 B6 s {5 I: z) B3 i K80 while (round--) { /* basic cycle start */ $ O( A( }2 I5 v9 v u x
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
) r% M6 s- f- x! \. D I1 \82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
. F! w1 m3 i C k. N+ n: O83 sum -= delta; 6 x4 U: F& K" D
84 } /* end cycle */ 5 P$ O. r# A- ~' T% Y
85 out[0] = ntoh(y); 3 }4 ~ B8 q% U! Q( I
86 out[1] = ntoh(z);
1 D- T, X! l. l+ H7 c87 }
* L9 e. S2 I& m9 t+ i% v! ]
2 W) c% N/ F0 ^4 l6 H5 P! h2 G需要说明的是TEA的构造函数:
, u q, a: x$ n8 \0 TTEA(const byte *key, int round = 32, bool isNetByte = false);
8 i# n8 h; Z# L! M% H1 B1.key - 加密或解密用的128-bit(16byte)密钥。 $ b/ d& X1 _* [. ^$ m
2.round - 加密或解密的轮数,常用的有64,32,16。
3 d+ z3 t$ N( f8 F# `7 s3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! : Y0 b6 Q, ]5 c6 |+ b
3 S9 f8 j. Q. {3 ?+ L6 j
最后当然少不了测试代码: |
|