|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
. w6 }7 B* N! A% Q& R8 l6 _ 2 #include <cstring> //for memcpy,memset
# C7 V, F& ^. X/ g4 A0 N6 T 3
' a# d# y; [% R' E8 j9 g 4 using namespace std; & ?- u/ L% b9 `* a2 I
5
& C/ [4 {- C, G; C 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
3 C. p: _! s& R. @ Q 7 :_round(round) # k9 d& M- |- g
8 ,_isNetByte(isNetByte) { 1 o( y+ O6 V' U' u. `
9 if (key != 0)
2 E2 C1 R/ s0 W8 s7 `10 memcpy(_key, key, 16); , t+ H; _+ ^4 k! G% X1 Q
11 else
/ o ]7 f2 }/ g f" Y6 m12 memset(_key, 0, 16); , C# J3 y$ p6 V8 e+ i2 M2 _
13 } # }3 `, ?4 M' f
14
7 t+ R9 i( u+ X) j- M% c: H" W15 TEA::TEA(const TEA &rhs)
: f5 k6 T. i+ g8 C0 k4 t2 I16 :_round(rhs._round)
6 w; Q" o; @# U8 s17 ,_isNetByte(rhs._isNetByte) {
( \) E: A9 @4 I" Z18 memcpy(_key, rhs._key, 16); 5 t* ~. L0 s& K3 h2 X6 _: ]8 ~$ H8 v+ N
19 }
5 v$ _0 Y9 {7 q20 5 f9 _. X9 m" A# W
21 TEA& TEA::operator=(const TEA &rhs) {
# S3 u7 z# e4 E' }% u- |: I22 if (&rhs != this) { 7 M1 ]3 B% y4 S* ?' t5 }
23 _round = rhs._round;
/ \. q6 {8 B, N/ I24 _isNetByte = rhs._isNetByte; 8 Y! C$ W$ |5 ~; O3 E1 u$ x
25 memcpy(_key, rhs._key, 16); # h1 m5 q) F I4 N
26 } 4 k" K- e: x2 x& W3 o
27 return *this;
( X+ k% _' J% C5 {* d& ~) k9 v28 } ) @6 M- _% w) [+ k" c9 d
29 , G9 q' C! c. t
30 void TEA::encrypt(const byte *in, byte *out) { 4 ~ w7 _' o& |6 V' g9 E
31 encrypt((const ulong*)in, (ulong*)out);
! k5 [5 j% T/ _8 @32 } ; g: z# L" j; h$ r+ b$ I) L+ ]
33
" O1 M" j* J# ?; x4 J* [34 void TEA::decrypt(const byte *in, byte *out) { : l( _. U# q [9 r$ }6 L
35 decrypt((const ulong*)in, (ulong*)out);
! {3 e! A/ h! }+ f+ p36 }
# |5 _4 Y# Q" s( T8 N _# [! c, i37
, M; ?/ p% P Q8 G: O }1 i38 void TEA::encrypt(const ulong *in, ulong *out) { . T- [2 V/ p0 G" k: s
39
! F9 B; }: M' r40 ulong *k = (ulong*)_key; - q* {, O, N( d8 t) Q
41 register ulong y = ntoh(in[0]); " a0 f# _% d" k6 N0 n' f6 w
42 register ulong z = ntoh(in[1]);
/ g' j) ~# `4 Q/ @, ^43 register ulong a = ntoh(k[0]); ( ]6 e! X* m( [2 g# o
44 register ulong b = ntoh(k[1]);
# U/ q. ~, S, {; _2 C& R. y) f0 k45 register ulong c = ntoh(k[2]);
! n) ]4 q* F0 ]2 o46 register ulong d = ntoh(k[3]); 0 Z, ]1 q: H+ F2 J5 h
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ $ @! E) L( |7 K* q0 ~5 Y: l% ]
48 register int round = _round; ( p3 p! ^: E3 t# `3 b
49 register ulong sum = 0;
4 o) f! H: @/ u50
: N7 ^* M+ t7 W. {- d5 U51 while (round--) { /* basic cycle start */ ' D, l5 u+ ?/ k3 x* H
52 sum += delta; * Q& q+ W. S! }& ^0 ~+ N6 B
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
/ @. a) I1 t( ~; j* m% n: T2 x$ F$ I54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); 6 V7 Z" J" E$ W
55 } /* end cycle */ ' r5 \& |$ W5 B4 e* W4 v1 f
56 out[0] = ntoh(y); # l- |) \/ ~/ o5 B% _. ]
57 out[1] = ntoh(z);
9 V1 g, Q# `0 b/ q. [& o58 }
1 u) U$ e$ C6 k; f% D59 ' M: A1 I4 s. |
60 void TEA::decrypt(const ulong *in, ulong *out) {
H. S1 t) a9 L+ k2 v' _% P61 . _3 }! T) M: |; p
62 ulong *k = (ulong*)_key;
( a3 `0 D0 K* v) s: u6 C63 register ulong y = ntoh(in[0]); 2 i2 A! q" o1 u
64 register ulong z = ntoh(in[1]);
' j% }8 [' X1 M i u0 R3 I65 register ulong a = ntoh(k[0]);
! K- p7 n9 _+ w# o2 m66 register ulong b = ntoh(k[1]); 4 `. a, L- D! g# A5 O# B
67 register ulong c = ntoh(k[2]);
! m0 b( {+ e( O+ ]7 j6 v; }68 register ulong d = ntoh(k[3]); 5 P" e7 f! ^& ^
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
3 z, J* A3 r) s# m! e! @* T70 register int round = _round;
/ J# y5 f- \" p# M) q71 register ulong sum = 0; + j5 E) l0 d3 r# r
72 - E5 L* F/ M$ u4 J* H- }
73 if (round == 32) ' A' l5 y- F8 X- |" T
74 sum = 0xC6EF3720; /* delta << 5*/ # b; G2 W6 M/ D* X$ x! u
75 else if (round == 16)
2 f) L( {0 } Q2 M% s0 ~76 sum = 0xE3779B90; /* delta << 4*/ 6 u/ |( c6 s0 S# p0 N
77 else " c: b0 H4 h7 G- v; D- u8 L
78 sum = delta << static_cast<int>(logbase(2, round));
6 T8 a% n5 T% u8 j. _8 t79
: H @0 C/ {5 ?4 C- I [5 I80 while (round--) { /* basic cycle start */ % u) K+ W; A+ N' Z5 u! c; S( z$ j
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); 7 b% v$ v6 e3 J( Q6 u1 Z3 w R5 O7 Z5 x
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
9 D( O0 z3 I M+ {83 sum -= delta;
5 P- e/ O% s% h9 v4 W" ?84 } /* end cycle */
* I h8 G, o2 h85 out[0] = ntoh(y); 0 z5 g3 ~5 ?8 j3 B% D: E6 e
86 out[1] = ntoh(z);
( G6 P6 \) r9 i87 }
7 |5 u7 v" K5 r/ }
. ^0 R1 B" \# H/ R5 p需要说明的是TEA的构造函数:
0 b( l. d( M" J; BTEA(const byte *key, int round = 32, bool isNetByte = false); " z& G! U* m: G4 ^: H1 Q0 a
1.key - 加密或解密用的128-bit(16byte)密钥。 : X t3 h! V/ }, f! N# C
2.round - 加密或解密的轮数,常用的有64,32,16。 / E+ r! c- a3 Y1 E3 W
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
, d, e9 ~$ ` o* \$ [# X4 L* T5 y, i3 L
最后当然少不了测试代码: |
|