|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
8 l: m3 i+ a" |9 W 2 #include <cstring> //for memcpy,memset 5 R4 t( H$ V3 x8 |
3
/ g* L0 x/ ^* W( T 4 using namespace std;
1 ^# h8 c: S: [ }" c/ n# Y 5 * g' W- x' `; d5 L, F
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
8 k& z `) z2 V* p6 S1 z7 Y 7 :_round(round)
, K8 r2 b4 h7 ` 8 ,_isNetByte(isNetByte) { 5 R. a8 P0 d% f
9 if (key != 0) 7 I+ A, Y$ Y/ N0 O
10 memcpy(_key, key, 16); ( k. l$ q8 O+ B/ C
11 else / h' V% N- R9 s! E& U
12 memset(_key, 0, 16);
* z" Y6 F# R" S+ f! P, S$ x$ o1 P13 }
" J( H3 D3 @( T7 z8 @14
2 J4 Q, g' R3 m2 v' I; H15 TEA::TEA(const TEA &rhs)
' I& N4 j" |1 Y/ V1 y16 :_round(rhs._round) / t4 z+ |% A: u7 C4 A; y/ T4 \
17 ,_isNetByte(rhs._isNetByte) { 3 w) }7 w# I+ f W2 t! c
18 memcpy(_key, rhs._key, 16); ; W4 m4 e' o" n. H& @
19 } b8 l2 x7 z2 ^5 P$ i% Q8 Y
20 * O$ m" n) @+ k" d% W u( E
21 TEA& TEA::operator=(const TEA &rhs) {
K, \( C+ q- i9 ~) Y& _2 Y; U7 X22 if (&rhs != this) {
8 _9 X# L2 s% k23 _round = rhs._round;
2 R/ s' Q$ S8 c) m24 _isNetByte = rhs._isNetByte;
# @6 ]0 j1 z# K1 W, Q25 memcpy(_key, rhs._key, 16); : U9 [" {7 T8 [1 p- ?! I
26 }
4 Z" Q6 U: U m- _6 W27 return *this;
+ Z4 r8 l& U$ c" q7 I6 R28 } ; r" z" i0 G: z; k3 }. c a3 c. h
29
$ \ h+ ~+ j3 H7 U. f2 j30 void TEA::encrypt(const byte *in, byte *out) {
5 l! L! G% D% L7 x4 a/ o" ^31 encrypt((const ulong*)in, (ulong*)out);
- N6 K! b% k9 p. e( Z/ @5 _( `: c32 } ) ` J, h9 g, p0 N) ?
33 ! K" r/ G: j( {+ o( F$ ?/ Z
34 void TEA::decrypt(const byte *in, byte *out) {
& r Y% s& T% @: D35 decrypt((const ulong*)in, (ulong*)out); ) O2 T7 i# n, {: @
36 }
) B4 t$ X6 d4 |37
& ~; k' U# A* c- ~7 w/ I' N% |38 void TEA::encrypt(const ulong *in, ulong *out) { 4 D1 c1 s; i- [" U& E
39
3 z: T' |+ |/ a5 u* w40 ulong *k = (ulong*)_key;
% }' |) f3 D" H' F# {9 d8 W41 register ulong y = ntoh(in[0]); 0 O( ]$ z6 V% \1 T8 y* u* J) }9 G
42 register ulong z = ntoh(in[1]); : s% J/ e; J8 V# R( e- I
43 register ulong a = ntoh(k[0]); / \, y2 X% s1 y8 L/ U0 F: \4 m
44 register ulong b = ntoh(k[1]);
7 U$ K/ T6 a' b3 g45 register ulong c = ntoh(k[2]);
* B' J9 c* K4 @& g46 register ulong d = ntoh(k[3]);
5 L* g5 W9 X9 F# E8 g4 ^' U47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
* N9 P7 q- l, R+ {( @0 W6 Y48 register int round = _round; 0 x( n$ A+ y- t- Z
49 register ulong sum = 0;
& L4 m; ^& \: ]4 L! j; h! K: L50
& g. p& H( ?0 K& Y# j. R7 n51 while (round--) { /* basic cycle start */ : U' I' i0 b% o- G; S9 l
52 sum += delta;
1 V; r8 H7 y3 n# B, T g! S53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
2 b! S8 h; p8 l' X- A0 Z54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); . y' f* D7 O) D# _
55 } /* end cycle */ 4 G! k* |# Z4 M$ w
56 out[0] = ntoh(y); " E! ^7 l/ ]0 {( E
57 out[1] = ntoh(z); - s7 ^; N: F0 W
58 }
8 X. F* ^. c' I% Q59 4 g7 Q% |) s0 F" K" g9 V3 K
60 void TEA::decrypt(const ulong *in, ulong *out) {
' _" p+ @3 b5 x, `8 M* M61
. Q% [3 s+ O3 S; \! c62 ulong *k = (ulong*)_key;
# I+ l4 Q$ Y `! @2 U0 s63 register ulong y = ntoh(in[0]); 5 U1 }* G. V! \2 p: q+ X- q% d
64 register ulong z = ntoh(in[1]);
: d9 N! ]* I- N65 register ulong a = ntoh(k[0]);
* b/ i: j# H0 p9 `5 n66 register ulong b = ntoh(k[1]);
* |" b% G" z- d, W- l) A4 W2 ]( g, \" o67 register ulong c = ntoh(k[2]);
: L2 f& l* u1 f% L* }- B4 [68 register ulong d = ntoh(k[3]); * c0 P6 X5 v# d3 d" s
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
9 @$ o! \; Q6 I# \ X: c: t70 register int round = _round;
3 W8 T- ^* P. h+ o. c e; d71 register ulong sum = 0; + y& [( C1 L! v* b7 v
72
# G0 t8 a! k; Y# I73 if (round == 32)
7 ]+ D9 g" a: d5 e W: f74 sum = 0xC6EF3720; /* delta << 5*/ 1 L [' r% T m# h" Y$ \, f
75 else if (round == 16)
- t* |2 @0 e" a1 j: T! m0 b76 sum = 0xE3779B90; /* delta << 4*/ 2 M1 n( U6 o" u7 v* f& Z p
77 else 4 a( A0 m9 s, p+ p$ F
78 sum = delta << static_cast<int>(logbase(2, round));
, N$ u- g) p# e" B79 1 q7 g8 W: f& R
80 while (round--) { /* basic cycle start */
) F0 a6 I7 g7 q$ H% r/ ^81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); ' \/ r$ Z) q4 h" s. A+ v
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); # b2 a% q0 r* B( Z$ v
83 sum -= delta;
2 R X/ w/ J% u8 ]: k4 S! Q7 ^" E- W+ V: k84 } /* end cycle */ 7 t4 S, d, A/ X$ T
85 out[0] = ntoh(y); % T1 n- j1 m6 T* Q
86 out[1] = ntoh(z);
' j! m% u7 m( ]3 O" g5 }5 A87 }
o, j2 u3 g0 R3 W, d, i2 g
( H: ~$ k% B5 X$ q! f5 m需要说明的是TEA的构造函数:
8 [# B+ g$ X0 t* j' Q8 dTEA(const byte *key, int round = 32, bool isNetByte = false); 9 c2 V) p" x" p( f) x
1.key - 加密或解密用的128-bit(16byte)密钥。
2 _& H6 I/ u* g5 L+ w2.round - 加密或解密的轮数,常用的有64,32,16。
& G* S4 q" p4 C: @9 P8 e! I3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! + q* ], p+ e7 A) e/ @% x3 n
9 r: D/ Y9 i9 r3 w3 I最后当然少不了测试代码: |
|