|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
: N: b' a. I$ C* P# s 2 #include <cstring> //for memcpy,memset
1 B+ o- v2 T2 K( ] 3 7 A" r7 t8 K& O7 g5 k* o1 }$ ^/ H
4 using namespace std;
2 a$ ~8 Q( s9 |. ?5 y& C/ x9 U 5 ) F: G/ J- L) E, E2 K
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
4 a/ M- b2 r) S- k, Q5 e 7 :_round(round) : N, D, M( X' n9 E
8 ,_isNetByte(isNetByte) { . H8 Q' w0 N8 I
9 if (key != 0) - m3 h' d6 {8 @) N u$ m* ~" @' S
10 memcpy(_key, key, 16); 7 M* b0 O p: k3 O5 C7 ?
11 else " j4 N- n: r( |2 i- M
12 memset(_key, 0, 16);
( x" d- I$ d" y6 ?/ e1 }/ B13 } 8 M7 v8 x' T$ J7 W+ B' `, s
14
3 g5 s( R/ X: i! n( }4 U15 TEA::TEA(const TEA &rhs)
8 { B* `; h7 W$ z" O6 R+ ~$ I$ \16 :_round(rhs._round)
4 n8 v0 b/ t7 t2 G% G4 V17 ,_isNetByte(rhs._isNetByte) { ) T+ w; X) y7 m
18 memcpy(_key, rhs._key, 16); 0 y5 S7 N( O4 J) O" ^1 c
19 }
7 A: H. N) R) ` u6 o20
k8 [" o8 d9 y% O9 d21 TEA& TEA::operator=(const TEA &rhs) { # A6 o' @9 |1 F H0 J; d$ R% m
22 if (&rhs != this) { . |. \! k. } ], R* u2 _
23 _round = rhs._round;
1 N/ I1 f/ n8 t4 Y8 ?5 `24 _isNetByte = rhs._isNetByte; 2 J) i+ [6 k9 {1 s. @+ q. Y2 d7 ~; l" ]4 D
25 memcpy(_key, rhs._key, 16);
& j9 w" o7 Z/ |1 g4 e, Y26 } 7 o6 R/ \! m8 E/ b
27 return *this; - q. v3 i$ _. |8 t
28 }
5 G6 m8 e4 I) U29 - b- q3 U/ o" ^+ n) s
30 void TEA::encrypt(const byte *in, byte *out) { 8 b) M& z9 [- `9 ]
31 encrypt((const ulong*)in, (ulong*)out); # W" l7 @' z) H2 O4 v0 m" c
32 }
& r/ i( j! q2 t; d; f: B/ V, J3 _1 W33
6 V' O- m1 m6 V- t8 A6 i7 \34 void TEA::decrypt(const byte *in, byte *out) {
+ D Z; k4 i) Q' H1 O N. E) G35 decrypt((const ulong*)in, (ulong*)out);
# F8 Z1 S& g& k, T2 W* k( r$ C) Y36 } % h2 c3 O+ M) `1 }1 ~5 }1 Z- K
37
' L ]1 g; r7 [5 l' m38 void TEA::encrypt(const ulong *in, ulong *out) {
1 B' |- g% q" `* D0 Y6 I39
4 q2 Y! X2 O- w4 Y3 z2 z0 A; v40 ulong *k = (ulong*)_key; ( d+ P J7 g. ^% |
41 register ulong y = ntoh(in[0]); 3 ?" B; P' J6 g9 J) b. u1 h
42 register ulong z = ntoh(in[1]);
! a: I* x3 s: @, g* c5 t0 q43 register ulong a = ntoh(k[0]); ! m! w3 {# J1 D) q+ i
44 register ulong b = ntoh(k[1]); 4 c- o3 U, @$ x6 }3 ?
45 register ulong c = ntoh(k[2]);
& ^" j5 ^( H- [' @ W6 A& H46 register ulong d = ntoh(k[3]); 5 m1 e. ]& z0 r4 M( e' D
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ . o$ `' X6 f g( h
48 register int round = _round; * p& I3 c& ?/ w2 U% d& G
49 register ulong sum = 0; ; D- w' V7 \' K: M3 n. L
50 2 X; M- H' o' P: O" y" F! I8 e
51 while (round--) { /* basic cycle start */
5 \, A: o0 G9 Y1 m! k7 p52 sum += delta; X; `3 x, m% ~. n0 e# V- S
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); 1 x% ~' J3 U6 x. @$ X( v- l
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); & ?& L) _5 |5 W* t9 P9 E
55 } /* end cycle */ , z" I" H! ]& v" D
56 out[0] = ntoh(y); ' a$ {+ i! J) s% V
57 out[1] = ntoh(z);
* B$ x6 H" X$ S6 Y58 } 3 `) B$ C. ]2 O
59 I% @5 g) x5 L$ Q# v" \
60 void TEA::decrypt(const ulong *in, ulong *out) {
& Q% h9 A! r# J, O+ y61 - Z% S4 m- u% q5 S$ B0 [
62 ulong *k = (ulong*)_key;
4 }: a+ n6 F6 p/ B W63 register ulong y = ntoh(in[0]); * c9 P) C+ w! z- D; D
64 register ulong z = ntoh(in[1]); / _/ T8 b1 |& G* F, H1 }6 O
65 register ulong a = ntoh(k[0]); 9 r$ Z# o" O+ b! A1 }, L j! i
66 register ulong b = ntoh(k[1]); - ^ y e: X0 m' d- y
67 register ulong c = ntoh(k[2]); 1 U" h4 q* A1 w2 C5 ]
68 register ulong d = ntoh(k[3]); - D' R! |' @9 ]) x7 I! I. M; G7 X/ R
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
/ h& ~/ R9 R" `4 k, w70 register int round = _round;
: K. M: K. `' j0 f# R9 Q' w( k71 register ulong sum = 0; 5 m* G- x' U5 d5 E7 l
72 $ g4 n/ D* u5 {$ V+ I& |4 C
73 if (round == 32) % q) E) @# u$ s) m
74 sum = 0xC6EF3720; /* delta << 5*/
8 p) F$ j: f3 T" W" j5 {( F6 ^75 else if (round == 16) 1 Q5 J3 b% R0 o n
76 sum = 0xE3779B90; /* delta << 4*/
6 A) G4 p9 z* B77 else + a$ g$ \& R' L
78 sum = delta << static_cast<int>(logbase(2, round)); + H7 o1 n `1 l4 c9 n' W& Q
79 2 ?1 j, j0 V4 ^* ?2 b# [
80 while (round--) { /* basic cycle start */ ' N2 x5 z' ~3 M) E/ b, Y/ g% D3 I7 j
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
! @& V" a) C9 u2 [' ^! \8 v4 r$ _82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
, r( j# P' D( A. Z. I/ f83 sum -= delta;
! \2 O5 K5 L# i+ ?2 u, o84 } /* end cycle */ 3 Q) k' b1 i- H5 k- E* c r
85 out[0] = ntoh(y);
2 K: [) c8 ~& k. c( e. O4 `# k86 out[1] = ntoh(z);
6 w# Z/ z0 s! j2 a; H87 }" k" n1 M" A+ h
6 L' v7 ]1 d+ X) Y2 x/ N
需要说明的是TEA的构造函数:
- f- k' d' s( ?" bTEA(const byte *key, int round = 32, bool isNetByte = false);
' F/ E3 D8 H# G9 K& ^4 S1.key - 加密或解密用的128-bit(16byte)密钥。 * c6 `& d9 W4 y* v% n) [4 [- s
2.round - 加密或解密的轮数,常用的有64,32,16。 , b! B T7 J) Y* v
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
' u! M, d) W# a* H6 u. k7 H4 J7 m2 K3 l: U
最后当然少不了测试代码: |
|