|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" - w8 F5 f5 K5 H5 }; P. r( a3 b
2 #include <cstring> //for memcpy,memset 8 I6 h& {. o9 a3 ^' ?6 P4 Y& H
3
7 v/ D' }% M( G3 D2 \ 4 using namespace std; . O. G8 V' l0 i; w& e; V+ r
5 / Y% L2 j" q/ l
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
# L! S' K Z$ g2 g) l0 O& U 7 :_round(round)
Q+ A2 c6 A/ y* L( I* ?( i 8 ,_isNetByte(isNetByte) { % s; [$ W G) O3 E9 |
9 if (key != 0)
9 J) U- C5 f8 c: q' b10 memcpy(_key, key, 16);
" P+ Y4 R, l: E$ F6 [11 else
- w1 r9 I8 a; h: C% s) g12 memset(_key, 0, 16); 2 ^8 X Q" n1 I5 S! A) u! v% P
13 }
) A) V7 T# c+ h6 N. c. W( n14
3 I) {5 ?2 {: r* s9 g/ E6 O4 I15 TEA::TEA(const TEA &rhs)
( v4 H, b5 }5 k16 :_round(rhs._round)
: H7 z9 A( ~* O7 l' M% V17 ,_isNetByte(rhs._isNetByte) {
! s* a* w C2 q0 P18 memcpy(_key, rhs._key, 16); $ _4 |8 O) q% b/ a
19 } 8 ^, ?5 V% O! q2 q
20
. Q: K( U5 E$ I! T21 TEA& TEA::operator=(const TEA &rhs) { $ J) _1 i: B9 \" X6 M
22 if (&rhs != this) {
: o! p6 t2 `" B23 _round = rhs._round;
+ a- K* L7 C) p8 e8 r! Z24 _isNetByte = rhs._isNetByte; 4 U: @3 r" l5 D0 d" {" W
25 memcpy(_key, rhs._key, 16);
% {9 T$ \' n1 i- T( _0 ~$ N26 } + u- L" P" I1 V0 H
27 return *this; ! M8 z4 m/ R+ H7 h2 e/ k5 D0 A
28 } % Q6 F5 K: Z" A$ T. f3 Z4 ]
29 8 h% j& ]2 X* u4 R
30 void TEA::encrypt(const byte *in, byte *out) { 1 g4 D" r& P" m ^
31 encrypt((const ulong*)in, (ulong*)out);
6 b. F: o8 m5 {" H: ]' z32 }
& m8 i& G& ~5 x5 t- _- O7 Y33 1 x: N) S' T% M0 W+ ?0 ?7 F
34 void TEA::decrypt(const byte *in, byte *out) { 4 c" l* U0 @% V: }' J
35 decrypt((const ulong*)in, (ulong*)out);
0 V D. u- M6 H) _8 ~36 }
: G) P3 v% m7 z: N( q' B37
% @# N& o0 _- U$ M& K3 A4 O8 I% R38 void TEA::encrypt(const ulong *in, ulong *out) {
0 l' z. t8 x3 v0 _; i- G0 p7 K39
6 A/ t! k$ ]$ x/ y9 `/ t0 I* d40 ulong *k = (ulong*)_key; ' G! K6 T0 ~$ a2 B
41 register ulong y = ntoh(in[0]); ' Q+ L9 p1 t5 P7 i7 a1 B) }! [
42 register ulong z = ntoh(in[1]); # G, {$ V7 e; Q& |6 ^
43 register ulong a = ntoh(k[0]); 6 i, m* P- {! f, k- u5 y: ^" x# F
44 register ulong b = ntoh(k[1]); 5 h Q( E# b# t; v/ m- q
45 register ulong c = ntoh(k[2]); + a7 e( }6 d& g" n% e
46 register ulong d = ntoh(k[3]); ! P# R7 D+ S, b
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ # G- X9 E8 \% Z) D# d
48 register int round = _round; 3 B: G& h: p% e5 q2 Y% T- _8 C) _
49 register ulong sum = 0; 7 u" U q, `9 O
50 , D$ G' X) {9 u; E9 I
51 while (round--) { /* basic cycle start */
" `3 o* U6 ]' Y, a$ ^2 X52 sum += delta; ; N( Q) k+ \; C! L, m4 y3 a
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); . y, Q# ~! ?8 P! E" C' ^( d. X
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); ! {6 g3 s: t7 U) Z& Q
55 } /* end cycle */ ' u5 O% l, x! t0 @( R2 e$ V$ ], E
56 out[0] = ntoh(y); $ V3 N! K) L6 d( W5 }3 P
57 out[1] = ntoh(z); & a' S7 S, c3 P& k# g: B7 n H
58 }
: m8 d& V! l) v6 D9 p5 g59
8 u, _8 |9 b4 |9 u% z60 void TEA::decrypt(const ulong *in, ulong *out) {
' {3 O/ ?' U/ j2 R* `; e61 4 N/ k p* Y/ D2 @1 P7 X3 e
62 ulong *k = (ulong*)_key;
; t9 j: f6 a1 K% |7 } U63 register ulong y = ntoh(in[0]);
! D6 t/ @0 ?- d0 P: V! |64 register ulong z = ntoh(in[1]); % M: @/ S' n* i% h) t
65 register ulong a = ntoh(k[0]);
" V* v, e" z5 |- V5 `. f66 register ulong b = ntoh(k[1]); ' D+ f' s6 j4 [5 f5 P4 N: |1 S' z
67 register ulong c = ntoh(k[2]);
x" S& l3 F& ?% q68 register ulong d = ntoh(k[3]);
& E( J; R6 ~/ x5 g1 E( o% p69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
, ] q0 T$ ]7 i* z# A1 S. a6 w70 register int round = _round;
) e! D5 N9 G9 o) c71 register ulong sum = 0; $ f$ u) ~& C6 M6 Y0 p4 e+ D
72
. J i4 D* n( j) @' O# h9 X73 if (round == 32) 4 t! a4 W% @9 m
74 sum = 0xC6EF3720; /* delta << 5*/
" \5 e6 N$ K, O! a. K75 else if (round == 16)
# f& O3 `: R/ u' ~76 sum = 0xE3779B90; /* delta << 4*/ 8 m3 E: y) u# R8 L) e% H1 U
77 else
6 r* C3 J [* i9 k5 Z78 sum = delta << static_cast<int>(logbase(2, round));
2 Q; d# h! E8 l6 B" I8 Y8 [% y79
* {3 A$ m" D8 B$ o% A/ x# h80 while (round--) { /* basic cycle start */
1 f9 @( J7 M( [6 D4 K+ \ X8 N6 Z81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
$ F3 |! R7 S( g. W" r# a7 O82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
9 A6 [, j1 S" O2 e83 sum -= delta;
7 ~0 [# `5 y3 L, h84 } /* end cycle */ U4 j# g4 S3 O/ g
85 out[0] = ntoh(y); d5 s8 S% t/ Y7 _, \6 j! p
86 out[1] = ntoh(z);
+ C+ N1 Y( Z5 p! N4 l87 }
; @% l, D# s' |$ [# b# p2 G( [* l+ R. a% S8 Z- D5 A" F& I/ \
需要说明的是TEA的构造函数:
, C+ w9 U) X- N* [9 gTEA(const byte *key, int round = 32, bool isNetByte = false);
6 \! }* V" k1 W/ ]- ]9 f1.key - 加密或解密用的128-bit(16byte)密钥。
" K; N4 N; D/ l7 c2 k+ m2.round - 加密或解密的轮数,常用的有64,32,16。 % Y5 G3 H* X6 N+ P
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! ; C( Z8 M- U) j$ B' a
3 ^. P& [! h) F' l% g! Y2 y
最后当然少不了测试代码: |
|