|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
0 v! C$ Z! S( P/ [ n" ? 2 #include <cstring> //for memcpy,memset
; h1 }0 W4 W3 n3 | 3 , P0 H' Z4 B+ [, p0 f0 j
4 using namespace std;
% @) @3 N/ ?" [5 b4 T. o6 n 5 ) t! o0 u! f# ^6 B. c
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
) w) p5 P, d$ Q; j7 ~- w. v; c 7 :_round(round)
" I) u+ g9 I5 v1 _! E1 l% H3 M3 d 8 ,_isNetByte(isNetByte) {
. b" x+ s- f6 T: \7 _ 9 if (key != 0) * ^* M( Z3 U9 k
10 memcpy(_key, key, 16); 4 z) I* Y4 Y: ^9 H8 E3 @
11 else
( }- ~0 ^; w- B, B6 {( z; ^2 ^0 C12 memset(_key, 0, 16); 0 }$ K& p ]4 I$ X2 X3 O; J
13 }
3 @; m1 Z0 H/ I Y# f6 S14 9 {3 n3 U. J x9 `) q; L9 v
15 TEA::TEA(const TEA &rhs)
' T1 X8 w3 E. M16 :_round(rhs._round)
1 \- z& O! h( |% {% g' x17 ,_isNetByte(rhs._isNetByte) {
+ g+ u* \) o" }4 X( c, h6 i9 Y8 g18 memcpy(_key, rhs._key, 16); % i8 K+ _6 B7 r& z
19 } 6 r: E+ V- q. W& |6 H8 a
20 % T: Z+ c7 T0 c/ X. |# r
21 TEA& TEA::operator=(const TEA &rhs) { 3 Q2 e! v9 F/ V6 F6 Y
22 if (&rhs != this) {
6 D% {/ p9 A- a3 [: X* B9 R23 _round = rhs._round; ' K* Z: j: t2 D4 X3 s
24 _isNetByte = rhs._isNetByte; ; v3 C% V% F- a9 T
25 memcpy(_key, rhs._key, 16);
2 g8 w1 Z J: x* z26 } 5 f" o5 B: q. `: F; a- X* g
27 return *this;
0 D5 z& N" G6 H1 H. d28 } ; z- L- N6 O% ?
29 # Q/ r/ q/ _$ J" t, V+ [
30 void TEA::encrypt(const byte *in, byte *out) {
2 M0 `: i) P5 G& |( o! b1 j$ o31 encrypt((const ulong*)in, (ulong*)out);
0 f6 d4 R: i n' T: N6 x32 } 8 O5 o# b. d2 J2 [& E0 Y1 H- R
33
$ ~% X: B2 |& A; W7 @" H34 void TEA::decrypt(const byte *in, byte *out) {
) F3 _( T0 Y4 \% n" r; n O5 g35 decrypt((const ulong*)in, (ulong*)out);
2 K$ | D1 F( @3 S36 } " F8 h: w' N o
37
, }" @/ j& M- E. P# Y38 void TEA::encrypt(const ulong *in, ulong *out) {
" f3 r8 E& A1 K( e+ Q+ n$ `39 2 e5 l- G9 A- |7 r e
40 ulong *k = (ulong*)_key; 2 z, t, K( }* ~& [7 s
41 register ulong y = ntoh(in[0]); * _' U% k& k; \6 z9 q1 @2 }. C
42 register ulong z = ntoh(in[1]);
1 M9 _# W6 M% r, x+ {43 register ulong a = ntoh(k[0]); ) M+ s7 ?- x4 I- N
44 register ulong b = ntoh(k[1]);
; B2 ^% U) t- J) r: _& `1 _+ ?5 V45 register ulong c = ntoh(k[2]); / r" ?- U+ U' a/ p$ ^
46 register ulong d = ntoh(k[3]);
2 H: `% ]* F" y6 L% C+ L0 Q47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ & U: S" T; U. X% Q# K% Y6 k( J
48 register int round = _round; : {6 b% @- ]- t v3 R- E
49 register ulong sum = 0; & O2 t1 i/ w- y$ {* p% C
50 M8 W3 P7 _$ e4 W4 N* \, H, r
51 while (round--) { /* basic cycle start */ / A6 s7 V9 x2 A R4 [6 r) u* o
52 sum += delta; `5 M/ b3 i2 S' D/ b
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
# N( y- x d1 u" @54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); ) Y1 {" R/ x4 n _5 m, ?$ N
55 } /* end cycle */ " i$ X. `/ l" ~" ?
56 out[0] = ntoh(y); : Z" i$ x, h4 v0 N1 B4 o& f: r
57 out[1] = ntoh(z); 5 s) e! U% L6 Z$ v7 C
58 } ; _( N) m% h' ]8 ]. u
59 - ?- K5 n& H# h8 k
60 void TEA::decrypt(const ulong *in, ulong *out) {
" P0 b* Q0 Q5 r& B61
8 F& D& \/ {: |* k% v7 ^; d62 ulong *k = (ulong*)_key; + m2 [# l- v, M1 v3 p# [1 W' [% }
63 register ulong y = ntoh(in[0]); F4 i" Y( W0 ]: y, q$ z3 W
64 register ulong z = ntoh(in[1]); . h3 P* C# j3 `+ e
65 register ulong a = ntoh(k[0]); % O. k: `9 t! n H, r* {
66 register ulong b = ntoh(k[1]); " T7 r1 o/ e: B' U; T! V
67 register ulong c = ntoh(k[2]);
+ e+ l5 d6 K; x u U* P y68 register ulong d = ntoh(k[3]);
. L$ n& D3 r# r9 r6 r- a% e& O" E69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
6 U3 [1 R: e# ]2 l, `8 B H70 register int round = _round;
' q, y) O9 i0 p6 K: O+ V. H* X8 p71 register ulong sum = 0;
: p$ ^- K5 {6 X4 D) u* x4 J72 6 @. f2 @5 `3 s0 m& e+ g
73 if (round == 32)
0 L* m( V* p% ?% T74 sum = 0xC6EF3720; /* delta << 5*/
0 B; @ o/ w4 u- ?& i% v6 N75 else if (round == 16)
' k5 D' {# u( ~8 ^. e76 sum = 0xE3779B90; /* delta << 4*/ * K' R+ E1 w4 |1 l8 G
77 else 5 Y* b1 z$ K& b8 `, n) _2 ~1 i% G
78 sum = delta << static_cast<int>(logbase(2, round)); + o- @- i& A$ ~- c
79
7 u$ i; C. a( s7 r' c5 _4 l& G80 while (round--) { /* basic cycle start */ * [8 d) F W' ~& |! r2 v5 a+ J, Q
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); , n! v A# j3 @
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
. P2 |! G9 S4 y5 ~ [83 sum -= delta; * N! k+ y$ G0 I9 Q7 K
84 } /* end cycle */ 1 }0 r* e& ^+ K6 X0 A
85 out[0] = ntoh(y);
: q7 l4 o% u6 P( z* U# W86 out[1] = ntoh(z); ( [, M' g. v; o7 J, f0 C4 j
87 }
3 E& G9 P3 n9 _& l7 Q+ J! O+ l
; \9 P& t, r' A8 O ~$ N1 }3 w需要说明的是TEA的构造函数: 8 E+ i# g; [8 f: H( M! o& z
TEA(const byte *key, int round = 32, bool isNetByte = false);
" V6 L; ~5 U% j4 V& B0 D, |0 I1 D1.key - 加密或解密用的128-bit(16byte)密钥。 4 H) | A8 l6 J* s4 @" c, B
2.round - 加密或解密的轮数,常用的有64,32,16。
4 `4 o3 e; V+ m7 x! ^3 m4 l. t3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
1 B6 x1 V5 ~1 `, [" g8 x' O2 D7 K& C1 u \: D+ E
最后当然少不了测试代码: |
|