|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
1 _7 M' F8 k3 z5 D4 S1 U! c/ J& c 2 #include <cstring> //for memcpy,memset 8 F0 f1 e( M/ `9 j+ @4 x( ?
3
( Z$ m+ z. y( N; E8 ^% Y 4 using namespace std; % T" N0 r0 z3 k
5
& n: B9 f: E+ X8 v: X 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) / e# g+ o" n p( ?3 D: N
7 :_round(round) 7 T+ `/ ~; X0 c, c' s' |
8 ,_isNetByte(isNetByte) { ' T b& z0 t6 v; D/ x
9 if (key != 0) + E/ A$ Q# F4 ^% E7 G
10 memcpy(_key, key, 16);
; W) t& a. k# a$ D11 else
5 C8 _& x0 e- F$ ]12 memset(_key, 0, 16);
7 _: J4 A7 `- \13 }
5 M8 K, t' u- x$ Z! C+ t14
' k- W$ P( A3 _( j' Z7 {15 TEA::TEA(const TEA &rhs)
1 y. y% u" _* C8 U: a& |& |. m16 :_round(rhs._round) - j2 `8 B* ?* D+ m6 j' K/ X M
17 ,_isNetByte(rhs._isNetByte) {
4 P/ Q+ D) \+ P' _9 E, a18 memcpy(_key, rhs._key, 16); , x& Y$ ~2 q( x5 M" v+ i8 D8 ?% Y
19 } ( h' r8 Z2 C% V6 q
20 ~# s1 r( `9 I9 s
21 TEA& TEA::operator=(const TEA &rhs) {
2 p* y9 c! x" ? O1 X22 if (&rhs != this) {
/ e1 Z$ J+ l8 y2 D# D8 F23 _round = rhs._round;
. ~( P% f8 \; e/ ?24 _isNetByte = rhs._isNetByte;
; O v2 q2 e$ v25 memcpy(_key, rhs._key, 16);
1 c( `' R e& K' u# D* v- }, ], B26 }
5 c; w9 \ q8 W% S27 return *this; ( w* I Z0 u# a9 y
28 }
7 N7 ~% g) t$ h# l29 ; j& b3 H/ E, x
30 void TEA::encrypt(const byte *in, byte *out) {
# W& J" G4 s/ p1 A3 X31 encrypt((const ulong*)in, (ulong*)out);
9 o1 K1 V7 Z6 c0 ^9 W32 }
2 t; \' q5 q; s6 |- J3 b33
; o* u$ B! M& u5 N+ `34 void TEA::decrypt(const byte *in, byte *out) {
$ I* }2 J% h/ P- Q35 decrypt((const ulong*)in, (ulong*)out);
" L0 u' L3 I: x2 ?% c36 }
$ D! I* r" H s37
: x# t& e% s8 R+ w$ [38 void TEA::encrypt(const ulong *in, ulong *out) {
7 q7 k" ?" J3 R) j8 h* Z39
# s8 T# T2 N3 X+ i$ U40 ulong *k = (ulong*)_key; . V& H$ d" ^: a# l) _
41 register ulong y = ntoh(in[0]); $ e% V$ S& b1 Q ~* |
42 register ulong z = ntoh(in[1]);
& }6 j; h: B; ^ R' i43 register ulong a = ntoh(k[0]); 3 l' |7 k- P" Q9 V, d9 E- G$ m
44 register ulong b = ntoh(k[1]); 9 h9 n: c K+ x, ]
45 register ulong c = ntoh(k[2]); . E3 e8 ~% k7 n- r
46 register ulong d = ntoh(k[3]);
! Z- G4 T8 Q* E+ y4 T0 M( y. X# ?47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
6 V3 y; N6 l8 m- ?& h' R' J48 register int round = _round; # ]2 t$ ?6 p* e) U- {
49 register ulong sum = 0; ! a6 X# O! _6 s& B
50
5 D" V: K ]7 |& c! N' i% N6 Y51 while (round--) { /* basic cycle start */ 1 N8 e; e9 Z6 `( [/ S$ t
52 sum += delta;
+ Y$ b7 e9 L; t53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
) E$ q* C6 g, F3 c; ~54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
: y2 l( t" @* D" N& p- O* W) k: E/ c55 } /* end cycle */ : G; d; [+ g* F* P# Y" p4 s4 e
56 out[0] = ntoh(y); ; n* ?! Y4 s, Z8 D0 V
57 out[1] = ntoh(z);
- C4 m7 C7 I5 p( ]+ K# }) {! l58 }
$ }0 X; r2 L/ G% G59 " ?3 N* @8 {9 p8 V
60 void TEA::decrypt(const ulong *in, ulong *out) {
( o: t0 h* `0 C( j% n8 T61
9 Y" w) J& {, I, L# |! c5 f62 ulong *k = (ulong*)_key; 4 ]4 Y) a4 d2 h1 ]
63 register ulong y = ntoh(in[0]);
6 j- Q- B5 L# ~0 Z! B64 register ulong z = ntoh(in[1]);
; l( R0 X4 @4 O+ {2 b* [65 register ulong a = ntoh(k[0]);
& n7 @2 @+ w8 c* I- B9 y; y66 register ulong b = ntoh(k[1]);
4 _( U8 Y+ Q" V$ O! M; t6 Y7 ?67 register ulong c = ntoh(k[2]); . `" B! L$ u: J- v4 a
68 register ulong d = ntoh(k[3]);
! g! [4 P3 a* ?' s/ ?69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ , N( q" h# Z$ |, Q4 l5 L; f/ g q5 g
70 register int round = _round;
4 n7 N3 i H1 ]( ^71 register ulong sum = 0; & t& o8 U0 w1 n
72
& x' ?3 A6 Y+ n J, w73 if (round == 32) - T5 J a, {+ M! z! c- y/ f4 ~7 _6 S
74 sum = 0xC6EF3720; /* delta << 5*/ + x. @' A5 V3 [- P
75 else if (round == 16)
4 ^! R& P" \6 v, w2 F+ i76 sum = 0xE3779B90; /* delta << 4*/ ! |% g2 H4 `8 R. D- D4 ~8 g
77 else
9 g# T# s& M4 c; r4 P$ K78 sum = delta << static_cast<int>(logbase(2, round));
, A8 r" x; U. s& }5 l7 l4 }8 D79
" o+ g4 s, `. x" [80 while (round--) { /* basic cycle start */
1 _/ a% m3 m. r( s" P3 Z: q. T81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); 3 ]: m6 h X4 K9 X7 S
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); " g; t$ ~/ Q) Q
83 sum -= delta;
' j$ ?* H8 U/ X6 @- v, L$ P5 p84 } /* end cycle */
+ G0 r' z# Z7 j8 y# l/ c9 b85 out[0] = ntoh(y); 6 O. Y5 W$ i& R
86 out[1] = ntoh(z);
" R# d7 A0 X8 J) @* @7 H87 }
/ j: F9 ?; w8 _5 ^1 z$ o4 u
. u5 M% O. n+ x9 N需要说明的是TEA的构造函数:
+ B* L) e9 u! Z. Z7 bTEA(const byte *key, int round = 32, bool isNetByte = false);
; f. E! X3 p( @& ^; @; [! l! i( d' i1.key - 加密或解密用的128-bit(16byte)密钥。 ; v5 p8 b, P* E$ |. l, t, ^
2.round - 加密或解密的轮数,常用的有64,32,16。
( x& ^$ r; r# E2 k+ m# U3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
& |- N8 v* b0 D4 O
, t- E3 N/ ^4 U& x @8 q! f4 V最后当然少不了测试代码: |
|