|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" , F$ P2 p# X1 |$ X
2 #include <cstring> //for memcpy,memset
]% N P, a' W 3 ! @4 t: ]. ~6 s) x9 f
4 using namespace std;
) `. ]3 ~+ L/ Q9 V 5
$ p( N/ q$ R/ R5 y% a# } 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) " \, ^5 B% u" q/ i5 M
7 :_round(round) , {0 k# w3 @* w' `9 {
8 ,_isNetByte(isNetByte) {
/ F& z/ a1 ]1 [' m1 O( ? 9 if (key != 0)
3 `7 b: E7 ^3 y. n/ G* S10 memcpy(_key, key, 16);
+ ^5 l5 w5 r/ T% L: v11 else
6 o" Y7 b: f I% Y) {; ^12 memset(_key, 0, 16);
! z) ^( A+ g% `* {2 n, e+ s) ?13 } " C& K( v2 w4 k8 l
14
/ R/ b1 C% S, Q- e5 s E2 n15 TEA::TEA(const TEA &rhs) / Q# e; z& g' h# M, X4 q( L
16 :_round(rhs._round) / v/ C4 l$ T: f- {
17 ,_isNetByte(rhs._isNetByte) {
* x: U& M: d; T! y4 _ C% d18 memcpy(_key, rhs._key, 16); 9 s8 k% r% V3 r! J- p; K- p; x
19 }
+ O0 }% H: w9 X20 , n# I" D$ h' m) d6 b
21 TEA& TEA::operator=(const TEA &rhs) {
% z4 X$ ` m& B' q; ~6 n5 M. {# F8 o22 if (&rhs != this) { . d) Y; I/ s# V) X' e; S, r
23 _round = rhs._round; 1 `) x/ U: V6 T' s4 i8 i5 N
24 _isNetByte = rhs._isNetByte;
8 g# y9 q" T* l/ |9 D; y+ e25 memcpy(_key, rhs._key, 16);
2 @0 X" f! U" }0 [2 w26 } 2 d" o0 p# D8 k
27 return *this; " c |0 Q/ N! |$ w/ H- E* }9 g
28 } : k7 o Z4 e+ g3 y! s- A M% ~& w
29
' j; f! G' P( I1 Q. i, j7 k30 void TEA::encrypt(const byte *in, byte *out) { 9 R) X: i3 ?, D, z" W8 D- F
31 encrypt((const ulong*)in, (ulong*)out);
8 ?! E. C5 p$ n% A/ F1 b32 }
- j1 K3 q: u; ]33
( N0 y- `7 z# H9 {8 _34 void TEA::decrypt(const byte *in, byte *out) {
* S- y( Z# q5 f- w c; I35 decrypt((const ulong*)in, (ulong*)out);
' ]: f4 E4 L1 r$ ?36 } ' I6 p* S% q/ m8 x
37 0 Q( k0 b1 Q' k6 Q6 f8 P
38 void TEA::encrypt(const ulong *in, ulong *out) {
! B- l. f; q1 C8 O7 d N( u39
1 T* { Q4 Z* \0 X) \0 _40 ulong *k = (ulong*)_key; 9 u+ Q) L0 |* ^4 }# U1 u
41 register ulong y = ntoh(in[0]);
$ b) c# @/ V9 M1 L) Q) O; o42 register ulong z = ntoh(in[1]); * l" [ K" k" u8 @* k
43 register ulong a = ntoh(k[0]); 5 ? E+ H! x. S! V0 i9 R2 Z
44 register ulong b = ntoh(k[1]);
8 c$ x+ f3 R9 q; g* z8 [45 register ulong c = ntoh(k[2]);
& \: u/ E" x& m! h5 A9 E8 I. H* i: p46 register ulong d = ntoh(k[3]);
; D# G: p" Y* r; _47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
) o" F) ]3 O' s5 h% q! ]0 t e48 register int round = _round; 1 I3 M& c( @0 j' }( w
49 register ulong sum = 0; 5 S5 j9 n/ b8 z; G3 O _
50 2 V" X/ n) E! ]9 m- |7 A: p2 D
51 while (round--) { /* basic cycle start */
- y$ ?" K4 m, D$ s; H/ w& f52 sum += delta; ! H: B# ~: ?$ o
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); 5 j1 y' Y: r' U+ L! s" Z5 |+ D9 P* h7 r7 E
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
! C7 Y5 J1 B( S1 _2 g; V55 } /* end cycle */ - s3 o. l; E: Q7 M
56 out[0] = ntoh(y); 8 X4 k5 q# L6 X1 V7 ]
57 out[1] = ntoh(z); 7 O+ m) `6 S. v
58 } * r3 b8 G* K. g# q0 }9 _
59
" e4 X- g# T. Y60 void TEA::decrypt(const ulong *in, ulong *out) {
5 S! `7 ~- y# [- J( c61 2 a, U+ A5 T5 w& f Y5 q6 c" V% c) Z
62 ulong *k = (ulong*)_key;
3 s" K4 Q( M$ d( B! L" `- A* X3 g& O63 register ulong y = ntoh(in[0]);
4 R" W, v) U0 Y; S! k64 register ulong z = ntoh(in[1]); ' [' @% J* ^6 L1 D" j
65 register ulong a = ntoh(k[0]); 3 R' l) H3 X5 t: R8 N5 }' ]
66 register ulong b = ntoh(k[1]); . c+ V) f2 L+ A) L) T8 @/ r' \: K! w4 G( `
67 register ulong c = ntoh(k[2]);
' @. f% P& Z) R* X4 [68 register ulong d = ntoh(k[3]); " |6 R, W: o: J/ ^' l% L
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 0 m F+ |7 O7 \ a
70 register int round = _round; * U6 m8 h$ N- T6 _, d2 ~
71 register ulong sum = 0;
$ b5 Q, x9 r7 L; n$ P# k* s% Q72 6 O# h. q1 C& o
73 if (round == 32)
) e2 p" n* C [" v74 sum = 0xC6EF3720; /* delta << 5*/ c. y, D- l' E' V$ _5 d* [% \
75 else if (round == 16) B( e7 e7 t+ l: a3 s; \
76 sum = 0xE3779B90; /* delta << 4*/
Q: k* q8 y9 T7 M/ U77 else 5 D. S: k- N) \8 U! V
78 sum = delta << static_cast<int>(logbase(2, round));
6 }' ~% h/ J5 S3 T0 q' |79
( d+ _4 H" r7 ]: j" G80 while (round--) { /* basic cycle start */
7 x% s* p/ |! e: L& {1 W# t6 U' j81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); B# d8 d) @ u. v* }
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
0 S: Q y: U, b/ e83 sum -= delta; * U5 t( K% I6 ]7 }
84 } /* end cycle */ % t/ n& h" z J H: X, P! E
85 out[0] = ntoh(y); 9 I, [' v+ V( o0 z$ X0 W
86 out[1] = ntoh(z); 3 _5 D `9 c$ p* X: h" I
87 }& j" g- S# S- `
- ? @+ z& K3 a
需要说明的是TEA的构造函数:
+ U# k- g& ~, Z+ STEA(const byte *key, int round = 32, bool isNetByte = false); 0 ~) l) {9 x$ F" T# L' |
1.key - 加密或解密用的128-bit(16byte)密钥。
@" h$ ]) U" ^8 O9 p- L9 y! T: X2.round - 加密或解密的轮数,常用的有64,32,16。
/ v1 f5 @' g( b, h0 r: n3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
9 J5 y& P, e. y- }. P! P+ ]/ m$ i9 w* Z( E2 a
最后当然少不了测试代码: |
|