|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" + @8 N' n: t% Z }9 W
2 #include <cstring> //for memcpy,memset
Z3 w8 I4 ` P1 e! w# E% p 3 3 O, M; a- x+ q) {
4 using namespace std; 3 O; s0 @+ b. y' f7 f' D6 ]
5
1 P: Q5 ]7 d& \ 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
) m, G" H' c6 Y# ] 7 :_round(round) 6 j8 [9 |6 e8 O& w# W
8 ,_isNetByte(isNetByte) { 9 Q* W2 ~) I. q5 P c6 p& e
9 if (key != 0)
! W8 O% F* q! ~% `3 d$ z10 memcpy(_key, key, 16); & r9 q9 g3 d) X
11 else
v8 |7 C9 S, _, m2 `3 I6 c0 w4 j12 memset(_key, 0, 16); * `% a& N# G$ @9 u4 c; F
13 } # I8 ?9 T0 @5 z* x
14
' h6 B6 X* x$ [1 s% }15 TEA::TEA(const TEA &rhs)
F# J% _0 j! Y" x16 :_round(rhs._round) 7 G* ]' g) S6 ]" e0 ^
17 ,_isNetByte(rhs._isNetByte) { ' J" C4 A9 ~+ t) T* w, i" S5 T6 v' x
18 memcpy(_key, rhs._key, 16); 3 T/ S, ]7 P. v
19 }
0 _6 @7 z; |8 |4 X20 ! N4 F4 K7 C# P7 _% [
21 TEA& TEA::operator=(const TEA &rhs) {
( q' ^; j. ~! C+ s2 ?% X y22 if (&rhs != this) { : y4 T' D0 a/ F( R! t& f5 {
23 _round = rhs._round; # V S' G4 G P7 s3 w- z. M1 ~- n4 ?
24 _isNetByte = rhs._isNetByte; 7 P* Q) P& i$ f: m( q6 ^0 W. {# z
25 memcpy(_key, rhs._key, 16); 0 @- D' d. {7 r# D; @, n5 Z
26 }
' T2 X4 ?& p+ Y | G- S27 return *this; 1 v" m8 C$ s6 }1 Q2 R5 x
28 }
2 @# ~, R' L: t8 M2 K29 6 A0 }( h, r. M8 M# x: e& j
30 void TEA::encrypt(const byte *in, byte *out) {
5 f3 U- K0 A* _3 B31 encrypt((const ulong*)in, (ulong*)out);
) z1 t" T1 P* R' R3 i4 M/ Y32 } & i, r8 |) r& r3 H8 i
33 9 f4 E$ p# `" Y5 \% I. x0 _3 G2 H; h" a
34 void TEA::decrypt(const byte *in, byte *out) {
/ M3 J3 ?) R/ z+ D1 i35 decrypt((const ulong*)in, (ulong*)out); 3 {; d7 U) a% \1 f$ p4 |
36 }
s9 p/ F2 K+ y. X) Z+ e0 H37
- j' d" q# Q$ l4 e: U! ]2 k38 void TEA::encrypt(const ulong *in, ulong *out) { / C$ o) s; N. c6 ^0 i, Y7 l
39 # T# I& n1 V+ N2 n# O& e7 |
40 ulong *k = (ulong*)_key; 1 U# |" [( f& b
41 register ulong y = ntoh(in[0]);
# U. W+ z, l2 w- h42 register ulong z = ntoh(in[1]);
' Z& |( `5 y: a43 register ulong a = ntoh(k[0]); $ A8 v- N2 I1 \! c* r/ E
44 register ulong b = ntoh(k[1]);
: |9 I9 Z p7 j7 Q45 register ulong c = ntoh(k[2]);
6 p0 H6 n% B3 u) u46 register ulong d = ntoh(k[3]); * F3 s4 R( F$ Y- j+ A+ {9 V
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ - }# Y/ {# R. d. j' y, X& w( m
48 register int round = _round;
2 I; ]1 R$ d4 ]) ]4 J2 f+ g0 h8 f49 register ulong sum = 0; ) U- C$ I; _7 c% m3 x! _9 b
50 6 X" F: [% Z- K
51 while (round--) { /* basic cycle start */
0 \5 V$ ?( z! K. p1 V52 sum += delta; : u4 N' s: s7 b4 w: I$ D/ L
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
1 l% t* w( a9 O8 Z, V54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); " P" [, L: F4 g5 L' i% W
55 } /* end cycle */
+ ~6 c/ M( V/ u" V7 s56 out[0] = ntoh(y); 8 o/ y2 n& E& s, k# |' {2 h' h6 _5 \
57 out[1] = ntoh(z);
/ b) Q e' f6 D58 }
- e/ W% a# H. ?3 ]# q$ e59
" ?; m) p2 R$ K- \60 void TEA::decrypt(const ulong *in, ulong *out) {
+ a* ]" | r( E8 s3 K6 {61
/ |* c4 }' e& i62 ulong *k = (ulong*)_key; , f" W- z0 ^' }
63 register ulong y = ntoh(in[0]);
, `# Q, a1 n* h- u0 Y64 register ulong z = ntoh(in[1]);
% Y9 q u) q/ e5 e% v( x65 register ulong a = ntoh(k[0]); 3 Y( S5 N. s% G
66 register ulong b = ntoh(k[1]); , s* I- }& ^0 S
67 register ulong c = ntoh(k[2]); / p& L& F3 k1 Y
68 register ulong d = ntoh(k[3]); % q! c- J! L# N" X2 B1 @$ h
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ , _/ A- R, ^( F a/ b! i
70 register int round = _round; + J. W0 m8 z# o" J* t# Q- c
71 register ulong sum = 0;
7 ~1 e: H1 P! M) p- d4 l. z" Z" ?72 / f/ I0 T5 c) a( V
73 if (round == 32)
, Q' i) l P. _7 c/ X9 y74 sum = 0xC6EF3720; /* delta << 5*/
% K, U5 d# C) d+ i9 R75 else if (round == 16)
% E0 y( \4 }7 y. e3 U76 sum = 0xE3779B90; /* delta << 4*/ - `* V0 s1 K! B$ {7 H. V* S6 q3 s" l
77 else
' [; Y! D2 n7 Q3 Z C78 sum = delta << static_cast<int>(logbase(2, round)); - s3 U! Q ^" l: p
79 8 U2 Z1 f4 ~# h1 V P: i' H3 j X% s
80 while (round--) { /* basic cycle start */ * e; p! w5 H- ]7 ?6 I
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); ! S2 U% k/ a* b$ N9 h+ P( h/ p- @
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
' J% M% m! t: T* r/ C83 sum -= delta;
$ V1 E+ y9 ^( q84 } /* end cycle */
/ W8 L0 S' s) h/ L1 t7 c d85 out[0] = ntoh(y);
( r; G4 A) d& N86 out[1] = ntoh(z);
4 [* N; M" |. h" _/ a87 }& Q3 k4 E1 l* S% m& G. L
( j4 K9 W) p4 K5 O1 \* p% ~需要说明的是TEA的构造函数: * r+ \ L9 \6 ?& A0 c
TEA(const byte *key, int round = 32, bool isNetByte = false);
; Y3 s+ q; a: _7 f1.key - 加密或解密用的128-bit(16byte)密钥。 ' [% L* |& A8 S" X8 @% M/ H& ^
2.round - 加密或解密的轮数,常用的有64,32,16。
# G! [! k2 v4 e! b, c* j3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! % K' z" v) A' w8 S' E$ s
4 q$ N" G! Z# _
最后当然少不了测试代码: |
|