|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
5 X: b- x1 X' \6 u# b0 L% z7 n 2 #include <cstring> //for memcpy,memset
6 r2 q9 T+ i3 R$ o$ v; ~+ v' ] 3
@; M$ B3 ~2 J0 N9 O6 Y; M' d 4 using namespace std; % d) a: P( q# z z0 S
5
" c, q3 y3 j5 i: I( | 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
# M% {. P' m7 I+ ~8 e6 J/ ` 7 :_round(round)
5 \- ?/ T; z- _ 8 ,_isNetByte(isNetByte) {
5 W- U" S+ `( Q/ h- ~ 9 if (key != 0)
) R, D. F8 W1 [10 memcpy(_key, key, 16);
6 [5 d6 g+ l" j* Z4 m11 else 0 M( O7 h$ h c s9 f5 n& p
12 memset(_key, 0, 16);
& R) ?6 j% G6 w; J0 t; m& z13 } $ ^3 S5 g2 P3 y" T3 O) `
14
r4 q# a: e* J7 y15 TEA::TEA(const TEA &rhs) / F2 V8 y7 k( T* ?7 A+ u* E
16 :_round(rhs._round) 8 P6 ?2 R& J ]& {, J! Z7 h) A
17 ,_isNetByte(rhs._isNetByte) {
" N2 ^! s9 v; S8 L2 k6 R18 memcpy(_key, rhs._key, 16);
) x* ^( u" ~) R+ h( P0 @19 }
- W% w+ s" r1 L2 q) d! }20
9 B" K* ~( l9 s7 ?, S; M; M21 TEA& TEA::operator=(const TEA &rhs) { 3 [7 ]5 T& [8 R
22 if (&rhs != this) { . I5 O, u' a5 U/ t4 i! l
23 _round = rhs._round; # |+ H& i5 s R7 O/ c
24 _isNetByte = rhs._isNetByte; {& [3 x) f6 h: P$ ]- X2 r1 Z6 O
25 memcpy(_key, rhs._key, 16);
1 l& }7 O3 n- R* i4 u3 [26 } 7 l6 p3 Q; k+ J" |: G
27 return *this; ) d$ q+ O \0 y3 s. ~
28 } 1 ?1 y$ K2 B: c( x
29 - H8 K% {0 Z# o1 `( U. M7 d
30 void TEA::encrypt(const byte *in, byte *out) { ! l" ]/ {% |5 Y+ L0 ?5 X9 {" }
31 encrypt((const ulong*)in, (ulong*)out);
4 _, V7 _ Y; z32 } 9 A& U1 W3 q) R) w& H
33 2 r* {% X; L" g- E6 D
34 void TEA::decrypt(const byte *in, byte *out) { ( l+ A( o3 X& s. p* z! F% Z! a; D
35 decrypt((const ulong*)in, (ulong*)out); 0 d g! |' U# k( Z. a
36 }
0 P- P+ d+ t/ e/ e! u8 g# A/ h37
' H& s3 K% x- w& m) M- ^5 j: M38 void TEA::encrypt(const ulong *in, ulong *out) {
" v$ c; C9 V) X39
! x8 Z( b* m! h: F40 ulong *k = (ulong*)_key;
# W# Y Q( B7 T) w4 @0 `' \7 L41 register ulong y = ntoh(in[0]);
9 G* {: H$ y6 ~42 register ulong z = ntoh(in[1]); 3 @& y) [ |) ]+ }5 M
43 register ulong a = ntoh(k[0]); 0 g( k( w, [7 G( j( B) E
44 register ulong b = ntoh(k[1]);
& p: T0 i6 ?/ \: b; ` w45 register ulong c = ntoh(k[2]);
; v) [0 g- c% h4 b+ e3 m; H( K' j5 k1 y46 register ulong d = ntoh(k[3]); $ S! y5 `* i: z$ x
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
% D' K: B% j" d# O( d9 x48 register int round = _round; 5 H6 d2 z9 v( g2 [% K0 v7 x" G. H
49 register ulong sum = 0;
' n% [, ?! V+ z9 {- r0 b) t3 N50 g: U2 I2 p3 m$ R
51 while (round--) { /* basic cycle start */ : x) k8 G8 x; R' X
52 sum += delta; " s& x7 \/ B+ \$ ^: f L
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
7 M# U5 i( X* N8 h% m54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); / w0 Q/ `- J1 U/ v; s) p a6 |+ ?) ^
55 } /* end cycle */ * [: u g7 D* \4 L3 |+ E
56 out[0] = ntoh(y);
2 j! _% n/ R, D! I$ |57 out[1] = ntoh(z);
2 c& U; v% Q5 @7 R58 } : c7 w: A# G [% w! u4 }: `. H4 v
59 ( Z- W9 @( H- V4 ]; o" ?; B
60 void TEA::decrypt(const ulong *in, ulong *out) { 0 s5 M6 _2 \" Y$ g; v7 w
61 0 D7 `+ X/ e# \2 M) \5 {9 J/ S: I
62 ulong *k = (ulong*)_key; 1 C% N- C/ }/ w; K' z# c" {2 G! R
63 register ulong y = ntoh(in[0]); 1 C+ Q( Q7 P2 ]
64 register ulong z = ntoh(in[1]); 1 e0 P, z, p& L9 _ ~
65 register ulong a = ntoh(k[0]);
; q& u$ s5 n3 O2 Z1 K- h66 register ulong b = ntoh(k[1]);
; h6 \& I5 J. L1 k+ A) Z67 register ulong c = ntoh(k[2]);
8 F- m5 A& R+ h2 x- K2 s% @68 register ulong d = ntoh(k[3]); 8 c7 I2 ]9 z& Q- K2 o
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ . V6 \$ H5 {; y* \2 s. L, ~% _
70 register int round = _round; # P; m1 a4 R. q/ Y0 w7 r# b# \
71 register ulong sum = 0;
9 w5 [1 E8 k# M2 ~7 D7 k4 q% x& y72
) \; q" D" u6 w' D3 A/ r73 if (round == 32) & k: [( s ~6 u& O+ u
74 sum = 0xC6EF3720; /* delta << 5*/
& {, M- u# P7 b' r6 y75 else if (round == 16)
* u: D0 H5 j- A# c1 |3 ^76 sum = 0xE3779B90; /* delta << 4*/
# u: M4 G7 q b5 m1 Y* d. W$ H77 else 7 f* X: q# N' m' F& U% Y3 a
78 sum = delta << static_cast<int>(logbase(2, round));
! X( L; V+ B7 k0 T$ q! M% \79
% c4 `; B! l1 O( h% V; _80 while (round--) { /* basic cycle start */ % Q# {8 Y& |% F7 q0 a$ ^4 H
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); ; H! ], i, D6 f8 o0 s' o
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); " ^ J5 R7 @2 u( |% R' @1 o
83 sum -= delta; ! X* W9 O1 k' @ k3 K( P& \5 I
84 } /* end cycle */ ; T w# W" A. t; ?5 X! p; Y, x
85 out[0] = ntoh(y);
1 }) H" r$ r2 r; B+ |3 F4 g86 out[1] = ntoh(z); + c& [' O' s: v% O R" o) N" _0 N
87 }
5 {" z0 @6 |7 F. |/ u/ f3 L) f& D) R& u2 G9 y' \/ D/ Q1 X
需要说明的是TEA的构造函数: " y O) R- x! [$ j7 M
TEA(const byte *key, int round = 32, bool isNetByte = false); " b( c5 N2 T |) Y! X" ]1 \
1.key - 加密或解密用的128-bit(16byte)密钥。 : a2 u* i7 o4 |
2.round - 加密或解密的轮数,常用的有64,32,16。 - O' ?5 G! q3 D, f, S+ S1 ]
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! . G1 |: ~6 x6 P8 s' h2 C
* r, U+ `3 P3 x: I$ m" `* N最后当然少不了测试代码: |
|