|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
) e6 g5 Q( a/ l* }6 q 2 #include <cstring> //for memcpy,memset
6 O3 F. T$ ] [8 v 3
7 ~( j$ d; K0 q. G }7 J 4 using namespace std;
; \" Q& J: o! Q1 N/ i* | 5
6 \) \- r, j) N7 _5 T 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) , |1 j, |3 u3 R4 {
7 :_round(round)
5 {0 W3 P) m* ?( f8 h 8 ,_isNetByte(isNetByte) { 9 i2 M7 w1 c+ u# O. @
9 if (key != 0)
8 {: B+ D, p, c! i8 e, }$ _10 memcpy(_key, key, 16);
; N. q5 k& a3 E6 q% `11 else " I$ u7 _3 I0 g' v0 P
12 memset(_key, 0, 16);
4 q3 o5 J: L& ]+ e! Y, `13 } 5 v! u3 L" E& j/ |6 E
14 ) |, u }6 v/ p
15 TEA::TEA(const TEA &rhs) $ j& Y; W3 w3 R3 ^' ?
16 :_round(rhs._round)
, Z% I8 O9 [5 E' i; f17 ,_isNetByte(rhs._isNetByte) {
& i& q: L: P- R; B18 memcpy(_key, rhs._key, 16); 3 r& T: p3 J$ |# ?4 X
19 } 2 Q' h% ?" V. Q9 g2 V7 k8 t/ P$ F' S
20 / [: q, @" p+ ^! `- l% [ u/ h
21 TEA& TEA::operator=(const TEA &rhs) { 7 ^2 }. Q6 C+ S7 w
22 if (&rhs != this) {
5 g: Z- b; Y8 Z0 |4 I: L1 ?23 _round = rhs._round;
% c/ Q# d9 U+ l3 V% h24 _isNetByte = rhs._isNetByte; 5 |0 r1 W y% f; p F
25 memcpy(_key, rhs._key, 16); h+ s$ `1 ]0 d. s6 A" a) v4 L
26 }
# u. l4 P1 O: w9 Y27 return *this; 4 I2 t' [" \: Z9 C. i$ m
28 }
U9 r3 O3 C! n* P3 M. o! K29 ' r; [. ?. V G* r
30 void TEA::encrypt(const byte *in, byte *out) { 6 N8 S) }% R3 I; x8 j' |* n- L' `* B
31 encrypt((const ulong*)in, (ulong*)out);
0 {% n/ c$ }# j- Z q; a32 } 7 R; T, a" q2 v2 J) P: J
33
3 ~' K( W. C' }9 i; q' _7 e& O34 void TEA::decrypt(const byte *in, byte *out) { + s1 a- ]( e5 v
35 decrypt((const ulong*)in, (ulong*)out); " a8 f& Q/ V% P4 R2 d
36 }
( G6 m2 A+ p1 z3 A37 1 N" C3 \6 j i! H
38 void TEA::encrypt(const ulong *in, ulong *out) {
* p7 L% F# h+ o* `39
8 T( X% A7 s5 Q7 r( S4 t' w40 ulong *k = (ulong*)_key; 9 `3 j, P! A4 E2 ^/ E; o
41 register ulong y = ntoh(in[0]);
4 s/ e: R- W) V3 _& L) f( m! o42 register ulong z = ntoh(in[1]);
9 @; `5 r" @7 h43 register ulong a = ntoh(k[0]); 7 y/ h. O" W+ _2 w/ V# U: M% Y
44 register ulong b = ntoh(k[1]); # E+ T: o+ d' ^
45 register ulong c = ntoh(k[2]); 3 L1 S' i/ A: i# T' U
46 register ulong d = ntoh(k[3]);
1 R( b9 a! d h0 K3 j: Y47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 2 p6 F, P) U# E* @; {7 e: H" K! g
48 register int round = _round; 1 L4 J- {- q" ^! u5 Z# w: z) v# |
49 register ulong sum = 0;
E; F0 k6 [' ?' l50
1 [3 k; D S; K1 u+ x& {8 v51 while (round--) { /* basic cycle start */ - J; g1 Q& u) }
52 sum += delta; * X+ K( X6 D9 D# f, [; d
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
1 D4 |3 p0 f" _, I: e54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
. i6 {% m9 n: n& e2 h3 d55 } /* end cycle */ ! R# D$ A( R/ i) r: `/ L
56 out[0] = ntoh(y); + n9 [1 ?$ A! l( q# y
57 out[1] = ntoh(z); 2 N! z4 r. j! A: [9 @
58 }
* x4 _6 U: S$ p1 }" O! P3 M59 4 Q y! C( [$ _+ T& Z2 ^
60 void TEA::decrypt(const ulong *in, ulong *out) {
) B. e8 J; ?& U: h( R61 P2 }2 r: H3 C7 q, L1 B3 \/ I9 a
62 ulong *k = (ulong*)_key; , y1 u! A% o( g& ]' B- x- P" Q
63 register ulong y = ntoh(in[0]); P% _$ G; _# W a- C# w
64 register ulong z = ntoh(in[1]); ) p2 c# v! x+ ` S# k
65 register ulong a = ntoh(k[0]);
6 y+ K) u7 J# ?9 \. b1 S" r66 register ulong b = ntoh(k[1]); 4 b1 e: ?" a3 @" h/ G
67 register ulong c = ntoh(k[2]); 3 h/ I6 d z- `$ n, S) N+ G& I, W
68 register ulong d = ntoh(k[3]);
0 \1 Y6 n2 k4 i69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
+ u/ _5 c% u9 m0 E70 register int round = _round; / [1 J; ^8 i5 _2 D2 L1 s" F% T9 y
71 register ulong sum = 0; ! g+ P/ }+ m- t/ U
72
/ V* g+ B6 Q0 X$ g: u& r h$ `73 if (round == 32)
0 p3 F6 @! j$ B, C) W8 E" ^' b& G74 sum = 0xC6EF3720; /* delta << 5*/ 8 l7 N& E4 M4 y# n9 A& I
75 else if (round == 16)
, x# Q0 f/ {* g76 sum = 0xE3779B90; /* delta << 4*/ + D! n6 U* H* M* \: l
77 else + b( i. p# p0 f5 \! ^& W
78 sum = delta << static_cast<int>(logbase(2, round)); 3 X$ G$ k4 Y' E" s2 H
79
9 ?- O O( T( c- S" y80 while (round--) { /* basic cycle start */ 7 \ |5 c; Q, X: e# n6 p
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); 1 S2 z5 l, U7 l, [ o+ W: a7 l
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); / {$ W3 m% J8 C% E* k$ e
83 sum -= delta;
" m4 A/ e7 L2 H; F84 } /* end cycle */
5 [1 |8 v& ?0 H* [& p+ e4 @85 out[0] = ntoh(y);
0 r, p7 e# s, Q8 Q5 r1 p86 out[1] = ntoh(z); 5 @( e+ s4 w' v# w1 c9 A
87 }
- u2 X( L- H! A4 |! g' z/ i- a; `1 B c/ Q* s
需要说明的是TEA的构造函数: 6 u: Q {% ?5 C& U% B
TEA(const byte *key, int round = 32, bool isNetByte = false); & l( |, h4 @0 p- v% @, A
1.key - 加密或解密用的128-bit(16byte)密钥。 & u. M3 C7 r7 |: T' D
2.round - 加密或解密的轮数,常用的有64,32,16。
! I9 }6 `( A& T# I* `3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
- z# ~+ d' c! D# k( H9 q
4 @; N+ B' b% c" \" ~最后当然少不了测试代码: |
|