|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
7 o% s* S! s, E5 J 2 #include <cstring> //for memcpy,memset 3 H) e8 K5 O8 l
3 0 P9 I( [" K# u* I
4 using namespace std; 4 Y7 l1 C- ~; I* b& R
5
0 Z ~7 S% o! |% k" H. ?1 a7 g! [ 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
4 y0 a! S7 Y5 r5 ?/ W' ] 7 :_round(round)
( s; [3 L% Y5 t9 k. C0 G% T 8 ,_isNetByte(isNetByte) {
6 S' }5 q! N% L& V 9 if (key != 0) 9 H/ F2 l6 b2 ~
10 memcpy(_key, key, 16);
. x) X" z+ q! `4 p% u0 R11 else
/ l, p* _) f. B; x( D% y* B9 q12 memset(_key, 0, 16);
* ~8 Q+ i2 p5 v5 g _: _6 F$ k. j6 l13 } $ a9 `* d9 ^0 F. t# \1 N& Q8 V$ g
14
6 \ ~% x# X, ~15 TEA::TEA(const TEA &rhs)
7 U- g" B; v* j% S5 T- f" J: a16 :_round(rhs._round) 6 e3 O0 ^9 g2 q# o6 ^
17 ,_isNetByte(rhs._isNetByte) {
( o, Z% N& o6 p% q3 R18 memcpy(_key, rhs._key, 16);
+ L- w- Z/ D2 u% @, T4 B* X7 g0 J19 } . C+ ^. M" j; o4 f! R
20
, U5 q' X! d2 h& p9 D' Y" T21 TEA& TEA::operator=(const TEA &rhs) { , x: ^2 j2 A, T( [: h+ O: `
22 if (&rhs != this) {
; D% n4 w+ M8 d) A# C+ r23 _round = rhs._round;
9 d$ p8 ~6 I- V: s& D9 b; x! P- I- f24 _isNetByte = rhs._isNetByte; 8 a1 v+ m) A# Z; }8 f3 J
25 memcpy(_key, rhs._key, 16); ) y9 L/ T, H/ v, I' ~# p
26 } 3 c/ B) x9 I4 B
27 return *this;
9 p2 ^6 R( Y& O5 ~28 } 3 \- Y0 V/ l' ^+ W2 Z+ p8 E8 Y- |& j
29 % Q5 X5 I9 }$ [9 @' a
30 void TEA::encrypt(const byte *in, byte *out) {
5 H# l/ U2 [' l8 z& p31 encrypt((const ulong*)in, (ulong*)out);
9 U4 v( m" m* T) u' u5 n" O+ @8 F( p32 } " O. A3 e4 S0 z5 b o) a8 ]1 |+ o/ }
33
; p" T" L2 _9 a5 ]1 G, T34 void TEA::decrypt(const byte *in, byte *out) { * f" L) j1 B3 T$ @% \- v
35 decrypt((const ulong*)in, (ulong*)out);
1 ^% }$ C, ^9 P2 C1 }36 }
9 X$ d% B1 j' W" o9 `37
3 \$ a/ g' V" g3 b# U, c L6 q38 void TEA::encrypt(const ulong *in, ulong *out) { ' E: M4 p z% V# g: o2 }' ^" Q
39 1 i6 {; }' ?; `* c
40 ulong *k = (ulong*)_key;
) s& v% w- m6 G3 _) M41 register ulong y = ntoh(in[0]);
8 @. P( w+ u; A, \0 d) ~42 register ulong z = ntoh(in[1]); , L% R8 J* v, M# M
43 register ulong a = ntoh(k[0]); 3 p2 f Z$ e8 Q/ I6 N& V
44 register ulong b = ntoh(k[1]); - M7 F# d7 k& Y
45 register ulong c = ntoh(k[2]);
' s, p. p1 A) H% J" Y: m, k3 L46 register ulong d = ntoh(k[3]); 4 A* ~6 ]; x+ L
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 2 }/ G2 v6 X# d1 r; q" {
48 register int round = _round;
6 E5 ?2 ~# N. L% Y" A1 `7 y' V! P49 register ulong sum = 0; # }- d: W7 S( b' a" L7 f f
50
8 a" w8 i' m3 a1 } M" [; D; z0 j# f1 g51 while (round--) { /* basic cycle start */
& _! @" }3 w. P4 U6 _) {1 s5 Q52 sum += delta; ! z9 @$ F* l+ {+ n
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); ) O# J" ~9 }" b* p) h/ X: Z
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); ' u8 M( u! [- c) u6 ~- e6 c( K2 a
55 } /* end cycle */
$ z- C$ m- w$ T6 z2 n56 out[0] = ntoh(y);
5 z6 i* O0 B5 G57 out[1] = ntoh(z);
+ d; n: I& p: Y0 n c* B; H7 Z58 } 3 }- _: E/ ?$ P# Y' z
59 8 F" d/ A7 x. J3 l% L/ C( a
60 void TEA::decrypt(const ulong *in, ulong *out) { 6 L1 k& ?: ^" u. ~4 J% R( r
61
& f) t, n* {7 [& C& k1 n62 ulong *k = (ulong*)_key; : \; T% Q& X$ S2 A8 u4 f8 C
63 register ulong y = ntoh(in[0]); 1 X/ ~7 |2 r( [7 ]# E" Q! y
64 register ulong z = ntoh(in[1]);
! a+ p8 P" B% F+ ^. H8 z65 register ulong a = ntoh(k[0]);
. ^; P* l [7 B" H! z B+ v66 register ulong b = ntoh(k[1]);
% @6 [: D; f- J1 t6 A$ J1 _67 register ulong c = ntoh(k[2]); + @) d8 r. X$ i% X; N& B- ?
68 register ulong d = ntoh(k[3]); 0 D- A2 F. U' v5 H: _) H% O
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ # E& C X7 j7 g
70 register int round = _round;
, i: |( T; u& r& O/ v6 b/ t71 register ulong sum = 0; 8 j1 i- ]6 w& h* d7 f3 q
72 9 r# ?& w, B. {3 i5 Z+ U% F
73 if (round == 32)
+ v G) L# U) o- w74 sum = 0xC6EF3720; /* delta << 5*/ ! W( |+ i6 d& U" w: j8 Z) F+ p% ]
75 else if (round == 16) ) q3 b. }8 y, {6 X
76 sum = 0xE3779B90; /* delta << 4*/ : k9 m$ |3 H7 J
77 else
2 d- d4 H$ k0 x3 Q2 p f% _! q78 sum = delta << static_cast<int>(logbase(2, round)); ; s; _6 ^ D9 U& ?, N
79
( o! e/ r+ Q1 _4 |4 W80 while (round--) { /* basic cycle start */ " v. t+ g" b6 Z$ C) U0 u- O% d
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); 7 M- {5 f& |$ `. T
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); 0 m6 R9 d5 b6 _. H$ p
83 sum -= delta; 2 l: `7 \' Q! d2 R
84 } /* end cycle */
; G" J" k+ C8 S# |2 S' K! x85 out[0] = ntoh(y);
b( j; j+ S# R: z6 K86 out[1] = ntoh(z);
6 `$ n D4 |6 o. [% v87 }
7 F+ }7 ?* \& G0 ~
0 j' P2 R5 h: {1 X7 Z" ^4 r需要说明的是TEA的构造函数:
+ G p$ n& i; a5 PTEA(const byte *key, int round = 32, bool isNetByte = false);
8 ]4 q6 D: X% R1.key - 加密或解密用的128-bit(16byte)密钥。 0 C7 a' \. D2 ~8 y
2.round - 加密或解密的轮数,常用的有64,32,16。 5 E9 d, {2 X) i( E4 a
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
! J# u; v% J- Y0 g0 _9 C( r. O, a: i, w$ Y; D( Y
最后当然少不了测试代码: |
|