|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
3 S4 w' \0 ` Q$ O$ N, b1 M, w 2 #include <cstring> //for memcpy,memset 6 h% U& }7 x/ u' s. V ?' `
3
4 W3 }' }7 j) {5 J C$ w 4 using namespace std;
9 p0 d! `* \/ [1 ^/ @) E 5
0 d8 Z6 N8 C9 x! I5 O( y$ d 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
- e0 T4 ?4 l; g. e" P 7 :_round(round) ' |( C% M; S. v" }" k# }
8 ,_isNetByte(isNetByte) {
1 q' E2 b9 \% y2 r& H& D3 ] 9 if (key != 0)
5 ~+ m8 D+ f8 T* L10 memcpy(_key, key, 16);
1 P3 \' ^+ ?# p4 d$ H11 else 1 r( m1 W- [+ p, {* }8 P# g( a0 N
12 memset(_key, 0, 16); # E5 [2 P) j+ w0 P9 {
13 } , m8 u, y* R' B w
14 9 t, E1 e' ]8 q g9 l8 S
15 TEA::TEA(const TEA &rhs)
4 j% O& i( n: d9 `3 D! x( U16 :_round(rhs._round)
3 B; F: } f+ V% `: k17 ,_isNetByte(rhs._isNetByte) {
$ ?! Q7 ?+ ~/ W$ N% ^18 memcpy(_key, rhs._key, 16); - L$ _! }3 X: O
19 }
& C% k7 r0 ?+ h. Y20 ' V% j* |5 s/ `. x' t5 Q
21 TEA& TEA::operator=(const TEA &rhs) {
- U5 ?, f) \8 o6 n- r! {22 if (&rhs != this) {
# o9 y1 `$ M6 c! E23 _round = rhs._round; 8 x* U4 i/ V6 D) V. ~2 I5 i- b
24 _isNetByte = rhs._isNetByte;
* X/ v4 a0 S0 K/ S( G25 memcpy(_key, rhs._key, 16); 3 y7 [1 \+ u5 N# V5 w
26 } * L1 Z% Y5 \+ h+ q
27 return *this;
, K0 c8 E! m( p28 } ; [* W5 A, a1 x$ J7 p9 Z6 g& R
29
; r6 N1 h0 b0 R* q6 K9 I30 void TEA::encrypt(const byte *in, byte *out) { & x' ?& g- S" _( t6 r' S: q
31 encrypt((const ulong*)in, (ulong*)out);
2 d; e/ H4 W" g" ^32 }
* ]3 _1 K2 T/ S) l+ s: h2 k33
% n. Z; U) ?, ?$ [% Y2 {3 k p/ \34 void TEA::decrypt(const byte *in, byte *out) { - T* x- g# S+ w
35 decrypt((const ulong*)in, (ulong*)out); 5 p/ b, K$ Q! n/ r# w* u
36 }
# I4 s9 M0 l! U3 V1 b* Q$ @37 ) H1 B) \# I2 A" |3 l
38 void TEA::encrypt(const ulong *in, ulong *out) {
H% R# `7 R2 h0 X; w39 % d. O8 [, D4 z) f. ^: ~4 u- L
40 ulong *k = (ulong*)_key;
1 G. p. I1 ^( F( m3 j! N41 register ulong y = ntoh(in[0]); 2 U: V) g: f4 E) \& I0 |0 U1 p
42 register ulong z = ntoh(in[1]); 8 R; f% A$ H6 q9 L5 M- F5 A
43 register ulong a = ntoh(k[0]); 9 q8 B _" b o2 ]
44 register ulong b = ntoh(k[1]); . K: e" Z5 E. \7 Q% h
45 register ulong c = ntoh(k[2]); . M ?, V" { w
46 register ulong d = ntoh(k[3]); + U( I1 ?: j' O$ D: g( ?1 ~" Z
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
+ B! j1 `, d$ w48 register int round = _round;
% s; H4 P* F4 P' ^$ K1 @49 register ulong sum = 0;
6 V# H' {0 ]2 Q& L2 A; |: I6 Q50 ) {1 R/ D) ~* D# v6 b
51 while (round--) { /* basic cycle start */ ' g8 @: c! L/ i; I7 F
52 sum += delta; 6 W7 [" ^+ }/ [
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); 6 a2 C4 g. O- O3 C
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); & N# l' S8 |5 V* T- [( [
55 } /* end cycle */
) m7 R3 W+ q0 m56 out[0] = ntoh(y); / q2 M9 ` v. ]! {! J
57 out[1] = ntoh(z); ) `$ L) r: E( Y) A5 X: `
58 }
* `* ]0 K$ ^* L+ `5 e+ N59
/ `5 m( b" }. b- y60 void TEA::decrypt(const ulong *in, ulong *out) {
7 {" J" G2 m; N0 |61 # q3 X f% R( W/ f* X: W/ ]
62 ulong *k = (ulong*)_key; . \1 W. z! j( D# |; a! \, o
63 register ulong y = ntoh(in[0]);
- I- C/ c# X U; e! V64 register ulong z = ntoh(in[1]); 1 K( ~, i& N4 [ S X
65 register ulong a = ntoh(k[0]); ) D; x" c' G7 h% p
66 register ulong b = ntoh(k[1]); 4 V5 B/ J: n5 O- t
67 register ulong c = ntoh(k[2]);
. S4 l; | O9 v$ B O/ T* B6 _68 register ulong d = ntoh(k[3]);
$ u( j7 V6 F$ Y* D4 q. _& h6 n! \, k69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
T- I- d" n4 M8 G( F5 `& `' E# ? E70 register int round = _round;
$ s& u, ?) m% w71 register ulong sum = 0; $ X7 ?2 K' N x8 R5 s4 a$ w# K: v
72
* b. B' B* n _( ~73 if (round == 32)
' C# s) T6 a$ t8 ^74 sum = 0xC6EF3720; /* delta << 5*/ % d$ m" \5 ]6 B
75 else if (round == 16)
2 _2 E2 f9 Y% f9 h( y! W+ ?76 sum = 0xE3779B90; /* delta << 4*/ 9 c9 [9 y7 f0 s( i7 {
77 else
/ ?, H& R i( r s$ i, O A78 sum = delta << static_cast<int>(logbase(2, round));
2 k u* [5 b% W, H' B2 G8 A79
" o1 u& ^2 b' Q; u1 K* D80 while (round--) { /* basic cycle start */
+ K D$ N. U" a0 e; X+ Q81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
5 g5 A$ G$ t- e& X, x6 t& D: D82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); ! N. k c9 r$ _( @9 Q
83 sum -= delta;
3 m7 x" r1 {6 P" \( N* o0 T: t84 } /* end cycle */ , F; {' j7 D: {
85 out[0] = ntoh(y);
7 ?8 {) l: { O% n86 out[1] = ntoh(z); 1 X! A* O H) h4 N6 V. d
87 }
9 `8 L" _0 B$ N% A3 ]3 } n* m7 M% a, a
需要说明的是TEA的构造函数:
0 }8 y7 N# X; ATEA(const byte *key, int round = 32, bool isNetByte = false);
8 G9 C) l# f7 q) H3 M9 I5 m1.key - 加密或解密用的128-bit(16byte)密钥。
* U& T _/ O: V( J N2.round - 加密或解密的轮数,常用的有64,32,16。
% b/ M5 x! o! A) m( V3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! 6 P0 z* ]9 \* k6 T1 T
+ X9 n( K6 ]. W% U1 W, {最后当然少不了测试代码: |
|