|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
2 n6 C1 F! M8 D/ Y 2 #include <cstring> //for memcpy,memset
/ [% ^; i" }# a4 [8 g 3
7 H$ B) ~9 W7 G+ T& Q/ S- A 4 using namespace std; 4 A7 M0 Q4 E o# A" S, v
5
H: C5 J1 w6 {; L# n 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
$ k: X8 v& U& H- y4 t- ]: k 7 :_round(round)
& P' V% g; U8 L) E/ A 8 ,_isNetByte(isNetByte) {
7 e; Y0 b* g, w6 L$ e0 ~, Q 9 if (key != 0) - V2 {, e: W* }2 B# A& u
10 memcpy(_key, key, 16); + ~$ }) F- T1 H; j# ]4 N
11 else
" y. k5 u! ]3 c& H& y5 o+ M12 memset(_key, 0, 16); % P1 o/ u6 ?& i9 \/ U6 G& ]+ O
13 } " R, Y& `) B' O9 J( [5 ]7 H
14 6 z: P8 { F% w7 m6 m. d* h4 [
15 TEA::TEA(const TEA &rhs) & N9 V: C) P2 n
16 :_round(rhs._round) : c; h% n8 H- B9 ]9 `% _
17 ,_isNetByte(rhs._isNetByte) {
& W8 d w/ a/ ]3 G A. r18 memcpy(_key, rhs._key, 16); 5 j& x! }5 _, x5 n
19 }
2 Y/ x }0 T1 i$ [1 I( `5 |" T) }9 C20
* ^* V# l$ X7 _21 TEA& TEA::operator=(const TEA &rhs) {
9 V& K/ `: }4 ]3 [8 v/ F22 if (&rhs != this) {
! P% L9 E" O2 r% y5 v' K23 _round = rhs._round; - F: G4 D! U9 I F' f8 n0 x* d
24 _isNetByte = rhs._isNetByte;
. E: y& P* x; `. h. n5 f6 W+ P25 memcpy(_key, rhs._key, 16); + }: M/ N& }# u. M9 e
26 }
! P8 k2 X% a' i. [( h- S: K27 return *this;
' y1 w3 R9 g6 P8 m; q28 }
3 ?. r, }( {5 t; o0 T4 U: A' Z9 k7 M29
1 I9 @1 h9 U. z) Q8 S" i* B) E30 void TEA::encrypt(const byte *in, byte *out) { 9 G* m. H; \8 z
31 encrypt((const ulong*)in, (ulong*)out);
0 k6 x6 Y; W: l$ @! ]. v32 } ! [2 R7 A- s. i$ F. K; `' q
33 - F, ^1 d. X$ ]- H7 Q7 k% O
34 void TEA::decrypt(const byte *in, byte *out) {
4 ]0 B1 k# G5 s$ T8 C35 decrypt((const ulong*)in, (ulong*)out); . M! F/ p) V! \# h
36 }
3 ?6 H6 j, y0 D9 |! U37 + L% h% ^/ w' |
38 void TEA::encrypt(const ulong *in, ulong *out) { / C3 D9 x0 y3 I% c
39
% N# O! Y" t' D+ ?40 ulong *k = (ulong*)_key;
" i/ S+ |& J, F. F; Z* w3 b41 register ulong y = ntoh(in[0]);
- q; t2 |' |" z9 E42 register ulong z = ntoh(in[1]); 4 ~3 Y* R; ]5 r: [# k
43 register ulong a = ntoh(k[0]); . u4 {, A0 J q4 A
44 register ulong b = ntoh(k[1]); & G' T3 q" o' ?1 u& z
45 register ulong c = ntoh(k[2]); 7 o3 M! Z- q! S9 m. {
46 register ulong d = ntoh(k[3]);
7 J7 J8 O% k5 I( G. e47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
7 p: Y0 F! c7 z7 x0 J" E6 D48 register int round = _round; 0 Q0 m# q9 m/ @
49 register ulong sum = 0; ; ? z: ]! _" V5 t3 [
50
1 `: O T, I, i! q& h: F51 while (round--) { /* basic cycle start */ ; w2 F' w7 n; u# q
52 sum += delta;
# ~* M2 p1 I {5 [/ H; h$ M53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
+ B& d; l2 u& c# J+ V3 K) I54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
! O* b* L" V B l' N: f+ A- R8 l55 } /* end cycle */
1 Z6 `$ R- V$ y$ t* J5 v c2 u56 out[0] = ntoh(y); 0 p! m" u- n# `3 q, b( g# f0 R4 _
57 out[1] = ntoh(z);
; _7 s- k0 ^( m. i+ H9 |58 }
8 t) J3 w/ }+ F6 n/ |59 5 m1 n! g' B7 l' ]' X4 [9 J
60 void TEA::decrypt(const ulong *in, ulong *out) {
/ ?3 M9 k5 Q' B. n* y# ]61
5 A$ F( y$ h# v, Z5 A# A62 ulong *k = (ulong*)_key; 7 ?( s# a* I. {8 ]3 x
63 register ulong y = ntoh(in[0]);
) `- }3 q' [; l. g* z# m3 n3 G64 register ulong z = ntoh(in[1]); 4 r U9 n7 y1 C& e: c0 c
65 register ulong a = ntoh(k[0]); . z8 Z( f0 z( V7 s1 q
66 register ulong b = ntoh(k[1]);
9 f! w" x Z. L) |5 B67 register ulong c = ntoh(k[2]);
6 [* u- v# P" s$ l68 register ulong d = ntoh(k[3]); & Q6 W/ j |4 i/ k1 u: B
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ & P L5 n' H0 G& U) k
70 register int round = _round;
- g; j# o g2 _: C9 b71 register ulong sum = 0; ' a5 l3 D2 y' ~& {6 S; N/ ?1 d+ \
72
! U" t5 m0 o! C' {; I5 G73 if (round == 32)
O0 {% M1 i6 n+ `+ G# E74 sum = 0xC6EF3720; /* delta << 5*/
% A) l8 G9 ^* ^8 ^" {75 else if (round == 16)
; m8 H; i" e4 W76 sum = 0xE3779B90; /* delta << 4*/
) O# V. i* v: s! z. y7 N+ r$ r77 else / z+ Z9 T7 v. M9 A* N/ n# p$ D8 y
78 sum = delta << static_cast<int>(logbase(2, round));
; V' h# a; ~0 _- U6 N: c9 T79 0 B# J8 j7 X! W
80 while (round--) { /* basic cycle start */ 8 n, Z! T. b l7 W
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); 8 `9 ?+ M. N+ _2 f% Z% t1 O6 l
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); % P, ]' T/ U5 j
83 sum -= delta;
0 V- B' M+ W" n+ K9 f/ d! [ r' i84 } /* end cycle */
' e4 e1 p7 g7 g: p6 h. T/ S85 out[0] = ntoh(y); - ^' M* V# \8 a, M4 T
86 out[1] = ntoh(z); # Q; U4 P3 I* F8 v+ }, r+ Z
87 }# f# b6 S0 h$ v6 g
$ C) @+ z9 @: K( u4 I; R6 K
需要说明的是TEA的构造函数:
+ P% ? t0 Y" _. j4 v4 vTEA(const byte *key, int round = 32, bool isNetByte = false); 0 q4 v. S, I1 P
1.key - 加密或解密用的128-bit(16byte)密钥。
4 M2 ]7 E) z r4 l; D6 S$ S2.round - 加密或解密的轮数,常用的有64,32,16。
6 ^; L6 _# O( Q; ~( l3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! 9 v8 L: L8 ?3 G
/ G1 g+ _% @9 W最后当然少不了测试代码: |
|