|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
$ v) i: ^( @8 r4 h; q& @ 2 #include <cstring> //for memcpy,memset
/ q: G {) p, R; l. M4 g 3 0 ?* t" A: }% y
4 using namespace std;
7 l- {: v; }% G# P) N. i. c7 k 5
# ]* ^1 }( z" ?7 Y; ?9 q9 B$ H* G0 Q 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) 2 k- O) F, _, t+ A0 x& I
7 :_round(round) - p* M9 M/ a- }, s- [+ Q7 m
8 ,_isNetByte(isNetByte) { ' o) R4 r0 m0 G
9 if (key != 0)
9 {, r- U( M V- q) e7 R10 memcpy(_key, key, 16); 6 t# o) B) s1 r ~! x4 |+ X
11 else ) o% u) I" k5 g; R2 x: k: t# _$ W" B( w
12 memset(_key, 0, 16); 4 V* W, C d/ |+ i# X5 ]
13 }
( o5 [# Z" U. r8 m, F; q+ c14
* M) r" P% p I' z15 TEA::TEA(const TEA &rhs)
/ {" A3 b% D! P- p& n; M- D' y1 |16 :_round(rhs._round)
3 `! Q& R; [* m17 ,_isNetByte(rhs._isNetByte) { + y# u! [; |$ r& T+ s" F
18 memcpy(_key, rhs._key, 16); , S2 f2 ~/ V( R: e8 w# b
19 } s: Z9 m, c2 |$ X1 Z+ U
20 8 m" g+ Q8 O* s; ^8 n
21 TEA& TEA::operator=(const TEA &rhs) {
# q& F/ h1 G9 G2 P22 if (&rhs != this) {
6 z' ~2 @ J' a9 ]23 _round = rhs._round;
: w* F) s+ p9 C% ^24 _isNetByte = rhs._isNetByte;
$ b+ y5 N& ?, p; e8 |2 t25 memcpy(_key, rhs._key, 16); 9 P7 E* P( V+ \3 O; i
26 } ) C; m( b P& `! m: n
27 return *this; 3 ?7 v# X, b3 k
28 }
% [3 j6 I! M2 ]3 y1 I29
. j) z+ m0 } J! Q a0 v4 g% s k30 void TEA::encrypt(const byte *in, byte *out) {
# y* J, ^( [& W% f9 L$ y31 encrypt((const ulong*)in, (ulong*)out); $ P) w' Q9 E/ h, c
32 } 1 ?3 |( M1 x) \" f1 |9 v
33
G7 f# F5 v! C: }. Z; n34 void TEA::decrypt(const byte *in, byte *out) { G& \6 r, E/ Q: ]8 s! @
35 decrypt((const ulong*)in, (ulong*)out);
- D# Y* b$ g7 T: B8 I1 G* N1 |0 q+ T36 } ; q( P! X2 O/ n+ c3 d: Q8 Z
37
' r( h' G; X" F, r* `' E38 void TEA::encrypt(const ulong *in, ulong *out) {
: r: ^! K5 ^% N3 ^; G) l39 3 v+ y9 W3 S/ [
40 ulong *k = (ulong*)_key; 7 `' o- C1 ]8 [# c, |. `
41 register ulong y = ntoh(in[0]);
& D. K# e, M6 J42 register ulong z = ntoh(in[1]);
* j+ l) K- \1 B, W43 register ulong a = ntoh(k[0]);
3 K0 y9 w- u2 A0 ]6 \1 y2 a44 register ulong b = ntoh(k[1]); 6 h$ _, M: d0 t+ v; w
45 register ulong c = ntoh(k[2]);
$ ^4 [( q' G& Z" Q# K9 E$ M8 A+ K46 register ulong d = ntoh(k[3]); 5 r# N, ]* O' b: f5 p$ ^9 i1 i
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
/ C6 Z* S& c+ N D48 register int round = _round;
; Z4 V) D/ J9 {" Z3 U49 register ulong sum = 0;
. f+ S( @" U1 o) k50
5 v* f" P- ~' p0 q3 ~, C51 while (round--) { /* basic cycle start */
3 y; t. S: ]& n, H" Z& T- t: o) @52 sum += delta;
: z6 p h" W/ \8 ^- o/ m53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
! E% V4 c" I+ E# f! q6 ]1 B0 ^( q54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
, @; ~. S% J9 N: V55 } /* end cycle */
) o0 L8 |1 s& f% l& `56 out[0] = ntoh(y);
6 O; \, V9 H: C' d& y# J2 F2 k2 ^% u57 out[1] = ntoh(z); ; |: {5 k( @* p, [5 A- W
58 } 5 X$ Q! g0 @8 h% ~" R+ W
59
3 p# _" u. ]4 H2 O2 M5 N60 void TEA::decrypt(const ulong *in, ulong *out) {
2 O- I3 z* D: r ^7 x0 h9 m61
3 \8 k0 L5 o1 ?+ O62 ulong *k = (ulong*)_key;
- e8 C: J$ j, r63 register ulong y = ntoh(in[0]);
7 w9 O3 m9 Y' o. w64 register ulong z = ntoh(in[1]); & C( |' d- M0 y: R# T1 h
65 register ulong a = ntoh(k[0]); " O( ^: V% C3 H O$ H; y$ N8 J5 L
66 register ulong b = ntoh(k[1]);
( F: I6 B3 N% Z* w67 register ulong c = ntoh(k[2]); - r* B$ A; ^" o# h
68 register ulong d = ntoh(k[3]);
/ t4 R6 f0 \0 Z, F9 y! @1 A69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ " U2 S9 \9 E" P' K) P
70 register int round = _round; ) f; P, X; D- }
71 register ulong sum = 0; 4 D1 h$ t8 V$ D7 X$ `6 f' ~
72 + Z" a* d1 k Y
73 if (round == 32)
/ I r* W. [- H7 Z" i' F8 `; G74 sum = 0xC6EF3720; /* delta << 5*/ ) [! |# H3 B2 Z: L& f& X$ r
75 else if (round == 16)
# f! }; m4 a! Q$ w5 [76 sum = 0xE3779B90; /* delta << 4*/ ) S3 ~8 f4 P% a- y
77 else
" T6 z1 a) h) c. s7 r& k78 sum = delta << static_cast<int>(logbase(2, round));
; P, l9 Y" G' g% B$ S' M) T79 / @# _% J. i# M2 {; I
80 while (round--) { /* basic cycle start */ 4 K6 }' ?7 @) h8 {
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); : y& z b2 F) z
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
, G* ~) E2 s6 }' ~8 @83 sum -= delta;
, S% g# P" T5 i" a4 s5 k6 _1 H2 ]84 } /* end cycle */ 0 e7 E% }6 @: ] l) q0 c
85 out[0] = ntoh(y);
% o6 q; i- R1 _/ f* Y7 h/ j/ {86 out[1] = ntoh(z);
* F, h7 l+ ?8 G% P; j' _87 }
& ]7 M M( L, ?6 {* F
$ X6 `- ^, i) e# _9 Z# P需要说明的是TEA的构造函数: ( j7 v9 ~- N2 {; v2 c
TEA(const byte *key, int round = 32, bool isNetByte = false);
& P* U C5 s `1 T1.key - 加密或解密用的128-bit(16byte)密钥。
, x i% V0 F/ n; O( a2.round - 加密或解密的轮数,常用的有64,32,16。
" y& q; t6 q1 u! L0 Z- j( D3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
; C9 u: h4 d* L$ m9 v1 t$ E$ P( t0 v& D. A4 g) o: j- M* U. ]% b
最后当然少不了测试代码: |
|