|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
9 F- [% R; T h, L/ @5 t' w( p 2 #include <cstring> //for memcpy,memset
0 {+ s! N3 t6 S0 U$ w \/ Y3 D 3
0 [7 }, x' g0 L/ \3 e4 O5 t. ^ 4 using namespace std;
; C, L5 J* }: X3 a/ r2 \ 5 0 y1 j5 G" u! w5 f7 h
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
+ J/ t! g0 p1 w, C, `3 a 7 :_round(round)
, H9 _4 g* P8 L9 }% I 8 ,_isNetByte(isNetByte) {
8 `1 B: n1 Y! H. _. z 9 if (key != 0)
6 B/ e8 ?1 c: q( n10 memcpy(_key, key, 16);
& _9 f7 f: I, H3 h" Y8 o+ M8 R2 \11 else 0 n2 |, s5 m" I4 U5 A; x& [
12 memset(_key, 0, 16); ! X2 J B0 @( I* r
13 } 9 D% Z' F" R- k, l9 S
14 ) y, k7 s* O/ ~: b
15 TEA::TEA(const TEA &rhs)
6 }8 y# B7 B, a: J: b16 :_round(rhs._round) * [8 @" l; J& J2 s! n
17 ,_isNetByte(rhs._isNetByte) {
7 V0 l l/ n3 |* F18 memcpy(_key, rhs._key, 16); ' n( N: Z; W, F
19 }
: `$ M7 {0 ?6 T5 A, t20 + }; ^9 \3 q. Y6 }
21 TEA& TEA::operator=(const TEA &rhs) {
% D/ |& [ ~* O& V1 g22 if (&rhs != this) { : B4 |& l6 Q9 ?" p [/ a& J
23 _round = rhs._round; ) h+ r/ q) I6 P
24 _isNetByte = rhs._isNetByte; 9 j, I+ {* Z) n8 g A
25 memcpy(_key, rhs._key, 16);
8 z8 g8 `$ X9 `/ x6 n26 } : \$ C& t. l1 Z
27 return *this;
9 D9 K0 V' \$ H' P28 }
7 K- \% Y* N! G29 8 s. H/ B% G5 U: J3 C, m" |" u
30 void TEA::encrypt(const byte *in, byte *out) { : g0 C8 K% p. @& T: C
31 encrypt((const ulong*)in, (ulong*)out); 0 f+ q0 Q# v h l: S* A
32 }
0 }% r. ]- O) E( \; j% D33 7 g, A' a$ N; E- x/ x+ F! Q
34 void TEA::decrypt(const byte *in, byte *out) { 9 W" o- |$ d9 m3 M3 r$ M
35 decrypt((const ulong*)in, (ulong*)out); 8 Y- r* Z# @/ M' V. e9 @! T
36 }
7 f2 ?4 U+ ~4 p2 M8 F x; Z37
+ D/ F* J3 N2 D, o# a5 @. u38 void TEA::encrypt(const ulong *in, ulong *out) { 3 h; P' `" `0 J3 R
39 * j5 v$ t5 n, ?% l7 E) s
40 ulong *k = (ulong*)_key;
9 @ R! I: U$ m3 E" J/ {41 register ulong y = ntoh(in[0]);
q. r2 ~% q0 p) S5 l! W0 L+ g- y42 register ulong z = ntoh(in[1]);
- m' V( ^4 J# v8 y* p# p43 register ulong a = ntoh(k[0]);
) l6 O8 \! B F% r$ f+ j% z44 register ulong b = ntoh(k[1]); # Q! r: E0 d; R
45 register ulong c = ntoh(k[2]);
2 V# k" l: s3 ~2 u1 h: W2 G46 register ulong d = ntoh(k[3]);
: y& U/ n: { t5 r1 ~$ ]47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ % K6 Q" U* l; z, x" v! |9 D
48 register int round = _round;
& C, |) j: i9 h! y6 C! G ?49 register ulong sum = 0; . O# H+ T, V. z2 [' O3 |2 ~
50 6 ^# I% j4 O$ }$ ?" T
51 while (round--) { /* basic cycle start */
' N0 W" M! K7 J! H$ t' x6 |# |; f9 c52 sum += delta;
" U8 f/ Z( |6 {: B I! l53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); 3 {8 J2 Y# P) T5 E) f6 }$ t3 U. Q
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
( U0 g/ {0 d. Q, {2 d55 } /* end cycle */
; i u1 d6 A, s, k56 out[0] = ntoh(y);
' o# E9 L8 F; F* f' S$ G* p57 out[1] = ntoh(z);
/ s: B+ p/ a8 C5 D4 t m. s1 d% @58 }
5 p2 n$ |, T9 G' A9 a, Z* t! l+ |59 $ q9 ~3 b8 ]# B
60 void TEA::decrypt(const ulong *in, ulong *out) {
! Z% M+ j1 `0 |3 j7 t61 & g I2 o, p5 ?
62 ulong *k = (ulong*)_key; 1 l# d# {! r# D2 b( A) W! P5 F4 s
63 register ulong y = ntoh(in[0]);
) a/ d& O- u8 r. C- W9 Z: C64 register ulong z = ntoh(in[1]); 7 W4 P: a) ]0 l d
65 register ulong a = ntoh(k[0]); 8 Q5 v* A- x1 o0 U; q
66 register ulong b = ntoh(k[1]); 7 ]# U4 a' O* D3 b
67 register ulong c = ntoh(k[2]);
: M6 j7 f' A; a ]( a9 \, H/ n; h( y68 register ulong d = ntoh(k[3]);
) {7 K) U+ S: c69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
4 s0 `: X F& ~3 W- n70 register int round = _round; ; f, c1 G$ k8 t4 t5 Y! M
71 register ulong sum = 0;
2 v; ^1 Z J x. H% j9 b) Y' L72 7 e. Z8 u' B& x) c- s
73 if (round == 32)
5 b% Y2 ?! |5 x$ P8 {7 |( {74 sum = 0xC6EF3720; /* delta << 5*/ 7 v: J+ i6 F9 n. Q3 P
75 else if (round == 16) ( S4 O+ ]6 l$ w2 P3 Y
76 sum = 0xE3779B90; /* delta << 4*/
7 h; i) x" u, w! E77 else , L; `3 y9 ^8 W# j* R; `
78 sum = delta << static_cast<int>(logbase(2, round));
; _, t5 s3 ~" F4 `- A p6 n79 % O+ P9 t' I2 J$ `6 E' \* q& m
80 while (round--) { /* basic cycle start */
7 r8 i; A7 ]% \$ V$ ~6 N2 `81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
6 U3 _( l9 j$ Y82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
6 c: w" h. r. c, p8 Z83 sum -= delta;
, U" P& b6 {4 C5 M84 } /* end cycle */
4 |& A+ J* d! C85 out[0] = ntoh(y); : a: |0 b9 C+ ]/ g& G" i
86 out[1] = ntoh(z);
, O; w2 E9 @8 n0 b+ P8 s* ~87 }1 N V: J0 |$ t1 c2 I
9 _9 H( l I* D, h! M需要说明的是TEA的构造函数:
! \3 y( f+ ]0 d5 e- P$ _0 f5 U1 jTEA(const byte *key, int round = 32, bool isNetByte = false);
4 d1 @3 H8 S% {, q$ ~5 M1.key - 加密或解密用的128-bit(16byte)密钥。
4 z, _) k" D& [. Z8 D/ Q2.round - 加密或解密的轮数,常用的有64,32,16。
/ Z9 _) |+ q2 b( c5 l. i: ~6 V3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
/ Z% d8 ?3 T; g v, D: \$ z0 t( w) k' }" m
最后当然少不了测试代码: |
|