|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
& U1 c& B3 e* b2 y2 E 2 #include <cstring> //for memcpy,memset
1 `5 ]& T1 T' I( S" \ 3 9 U+ y$ D9 c; T3 Z! }
4 using namespace std; 6 F/ Y% B! Z5 f: C/ w# J
5 . `% [' c: F) k! B" C; s
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
( [' G. Q) p& Y1 k7 H' Z 7 :_round(round)
' H8 g3 e c* a1 q 8 ,_isNetByte(isNetByte) {
( U" w' K9 h$ x Y- O) x3 ] 9 if (key != 0) 6 V& t2 x: \2 |3 f3 M6 ^1 ~
10 memcpy(_key, key, 16);
* \" P" n: @. M& ?6 K) H11 else
* E6 [' T$ Y, T1 X; @( W12 memset(_key, 0, 16);
4 x* f: N7 L9 x* B13 }
' B) D: y; l. }. J3 g9 N- R' u7 U14
' R) W$ d" o/ @. r" d15 TEA::TEA(const TEA &rhs)
6 ^6 H# H0 T3 r% T; R16 :_round(rhs._round)
5 M( n E; a# c9 s( n17 ,_isNetByte(rhs._isNetByte) { % l7 b8 m, Q1 C/ L6 m3 f
18 memcpy(_key, rhs._key, 16); 2 g' A; t1 q3 U7 n3 F
19 } 4 \& _! l+ p+ e9 E3 S0 @0 ?7 p
20 $ V4 m: O% w; K! ^$ B
21 TEA& TEA::operator=(const TEA &rhs) { , u( r! B6 X4 D3 m
22 if (&rhs != this) { 5 t! G( W: s ]
23 _round = rhs._round; ' F' U% o" W& e
24 _isNetByte = rhs._isNetByte; 8 }# L; S: n- P, H/ r' x7 J
25 memcpy(_key, rhs._key, 16);
# D4 ?1 s, y5 {26 }
" W2 n4 Y# D% `27 return *this; , W/ w4 J0 U, ~* Q( L! u8 H
28 }
8 s$ \' y6 ^# S W% t6 {4 g29
0 `. C$ s% v" y4 J! r w7 p0 C- C30 void TEA::encrypt(const byte *in, byte *out) {
c6 i7 l/ l& X/ r' X0 _) G7 e+ t31 encrypt((const ulong*)in, (ulong*)out);
5 w1 a, q, t- G32 } , R: K2 J2 k5 E# ?+ E. D
33
: S: D0 ]; C3 _34 void TEA::decrypt(const byte *in, byte *out) { 4 D( J" h2 X$ {8 t& Z* t
35 decrypt((const ulong*)in, (ulong*)out);
" k7 B* s9 c& N( ]9 R6 I36 } w7 R& Z) n9 E: E' e: s( K$ d
37 - ~9 G" w! s5 |6 Y6 w0 N4 V8 Y
38 void TEA::encrypt(const ulong *in, ulong *out) { 0 f2 @8 a9 e* q' N) j( x1 d
39 ' _2 m3 L( J% T
40 ulong *k = (ulong*)_key; ! }7 P4 J/ s3 F4 [4 ]7 ?" g
41 register ulong y = ntoh(in[0]);
9 y. u# g, T+ O3 h, J: s3 x42 register ulong z = ntoh(in[1]); ) N% n& b* |0 v% c& V
43 register ulong a = ntoh(k[0]); . t$ b1 F v8 E3 [
44 register ulong b = ntoh(k[1]); ) f" v) C9 P9 c2 G2 K: [( o& D! s
45 register ulong c = ntoh(k[2]); : ~* h* x4 f# a' T8 x9 q! j. U$ [- C
46 register ulong d = ntoh(k[3]);
2 ~8 W+ W1 g2 w% M4 K% x( C1 x47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
! a( ]( ^* K& F48 register int round = _round; , Z$ G7 u$ R+ v+ U* b
49 register ulong sum = 0; 5 f# D( l l) s- S( w8 Q r
50
. L" Y1 \. I6 ]1 c51 while (round--) { /* basic cycle start */ 7 o1 h( ^/ X5 H+ w, Q
52 sum += delta; 8 ]) h) `+ T; A8 X- Q6 F; {) z
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
8 F1 x6 s9 X* h, O% X3 e ~ Y54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); 2 f. x! k; k9 Q; Y5 B$ F' Z
55 } /* end cycle */ + J9 |! {& ~' K$ N
56 out[0] = ntoh(y); 5 @) t: L1 {" X! V! T: Z
57 out[1] = ntoh(z);
. C, T# g1 U# O( ~58 }
0 V8 e) G2 X7 k; M1 H, O59
9 _* D/ c0 f T* U5 {3 T! n60 void TEA::decrypt(const ulong *in, ulong *out) { 6 W1 }- H# p, E8 y3 e! h
61
3 _+ r& A& A9 } i- e" X62 ulong *k = (ulong*)_key; 9 U/ ?) q- I; {: D% z$ b
63 register ulong y = ntoh(in[0]);
: [! N) h: f. ]! d1 O64 register ulong z = ntoh(in[1]);
5 r9 i0 s# K0 C8 }$ Z! j5 Q. F( |. w65 register ulong a = ntoh(k[0]);
. ~. d7 [7 S8 e* R, K66 register ulong b = ntoh(k[1]); % J5 n8 d4 a5 Q
67 register ulong c = ntoh(k[2]);
% R- N( _( g- [3 o68 register ulong d = ntoh(k[3]); 9 }9 Q8 q2 `' B. t- b$ O) d4 s
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 9 F9 z( E1 T0 C0 N6 v5 S% W
70 register int round = _round; 6 A" \$ U" a1 S& I) ^; J
71 register ulong sum = 0;
2 u2 x, q: t0 H- Q! l6 @72 ( I: F4 M: z3 V+ R
73 if (round == 32) 2 M! ?4 i" g7 T8 X# Y' Z
74 sum = 0xC6EF3720; /* delta << 5*/
4 @1 ], N) B) t7 L75 else if (round == 16) ! b( c6 l$ R! c2 N' [( S4 s4 y" l
76 sum = 0xE3779B90; /* delta << 4*/
/ k3 ~% \+ W6 N% V0 k77 else
`# `. y/ @' f78 sum = delta << static_cast<int>(logbase(2, round));
, K g* H" \, |1 h79 ( a: o. O' K8 A* p
80 while (round--) { /* basic cycle start */
! p- `5 D3 ^6 y+ L; m" u7 z81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
3 I% Q6 d, y+ {7 J& o2 I# J82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
; T( z4 ] J5 a, P q83 sum -= delta;
7 ^( m9 J7 E; m84 } /* end cycle */
; ]. }8 e$ U( \7 ~5 a$ S85 out[0] = ntoh(y);
' F- y4 z6 D$ c: d% `6 O# Y86 out[1] = ntoh(z);
5 N2 A6 S+ V& y l7 L, I87 }
. n! |0 [- ^6 k7 a0 {$ @- M
7 K/ N: [7 a2 z需要说明的是TEA的构造函数: ! W1 Z5 Z% N3 z* {) l& L" t
TEA(const byte *key, int round = 32, bool isNetByte = false);
) W u# i& X, @/ ]+ }1.key - 加密或解密用的128-bit(16byte)密钥。 6 |: n: {1 }6 m s3 ^, X
2.round - 加密或解密的轮数,常用的有64,32,16。 T* n: `: {6 l+ O/ w
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
8 \# S/ ~: ` k& h+ m b( S
3 ]' j+ H- Z+ V; {最后当然少不了测试代码: |
|