|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" 1 W6 ?6 e9 q1 @1 _5 I. `7 E7 C
2 #include <cstring> //for memcpy,memset
. [' s# S) g6 ]: E( T E; A! \ 3 0 |" B% C/ N" S+ i* l5 o3 p$ A+ g
4 using namespace std; % }8 Q, }5 p( S! q7 d4 G: D1 ?
5 ( X, c3 U+ b0 t7 K% l; m/ F1 p9 o
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
" h( J+ {3 q6 `' Q& ^ 7 :_round(round) 1 z1 B# G! S, d$ w
8 ,_isNetByte(isNetByte) {
/ x) M$ \3 I. U! i5 o) M: n 9 if (key != 0)
" c" Q2 P+ I9 N4 M/ ^2 G10 memcpy(_key, key, 16);
9 Y. N, L. \% ^: R11 else 0 V, Q& M" Q6 [3 a
12 memset(_key, 0, 16);
& f5 d2 _6 K- o13 } 1 O! Z2 `( P0 j
14
- x1 g- Q% }% F+ @* M15 TEA::TEA(const TEA &rhs)
- e* m$ U% J$ G1 b) y% G16 :_round(rhs._round) : ~6 A5 X5 ^7 b3 h6 W a3 I2 d& E+ x6 ~
17 ,_isNetByte(rhs._isNetByte) { $ [# s! R" v6 I% M
18 memcpy(_key, rhs._key, 16);
4 f5 w. b+ G' P2 C) ~3 @19 } " H5 ^1 \6 F* P- s
20 - z4 ^1 `. U& p2 O& c9 N5 X
21 TEA& TEA::operator=(const TEA &rhs) {
c5 l* X. [9 d0 C4 x22 if (&rhs != this) {
7 {% \/ r0 Z2 c' b23 _round = rhs._round; * b' t* m8 m! x& W
24 _isNetByte = rhs._isNetByte;
% S* F$ O& m4 J7 d$ P4 R' L4 P25 memcpy(_key, rhs._key, 16);
/ a9 C/ ?# E6 y- D26 } . B: X- o- h/ _# @- y7 S
27 return *this; # b/ E& |- R* a$ d; A- g' I6 o
28 } 1 ~" X9 M& v, b! B- O& f! T
29
; A/ D6 r5 e0 Z; H3 t5 R30 void TEA::encrypt(const byte *in, byte *out) {
: w$ p' N; n3 |) z/ p% h/ V31 encrypt((const ulong*)in, (ulong*)out); $ i/ \3 H5 `( ~/ ~/ V1 _" y. [
32 } ( b/ G& e: r2 c5 c. [9 e
33
- `8 M1 t/ B3 q9 U& S34 void TEA::decrypt(const byte *in, byte *out) {
7 f7 O2 _1 F5 E$ G35 decrypt((const ulong*)in, (ulong*)out);
, z' N9 V3 w+ P& M36 }
: H3 u% A- Z! ` Q37
( a$ e" b: ]0 k9 i- I. y38 void TEA::encrypt(const ulong *in, ulong *out) {
+ s+ d; ^$ M: j& [39 7 V7 w5 T( K% b3 a% r
40 ulong *k = (ulong*)_key;
0 M7 q" R# N F& R$ o* f }6 R41 register ulong y = ntoh(in[0]); 0 n) ?- [- G) H* O" `
42 register ulong z = ntoh(in[1]); / a& j; z/ `9 M( {1 \* j) H
43 register ulong a = ntoh(k[0]); 0 z9 W) o! C6 Z
44 register ulong b = ntoh(k[1]);
" |, N7 Y# v7 N& i45 register ulong c = ntoh(k[2]); : l2 ~/ o8 j# e) r
46 register ulong d = ntoh(k[3]);
E( v: Q0 U# S5 B7 w: n47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
2 O( S; z" k, d8 Y7 {0 c48 register int round = _round;
& h( B* o/ n; P8 S/ C6 E" P49 register ulong sum = 0; . x( \7 R+ F" o" a, |1 r' P1 J
50
' }' A7 p+ Y, D# ~( R1 Q' j51 while (round--) { /* basic cycle start */
9 j4 D* u; i$ @* p- X( w6 \52 sum += delta;
6 N, I( T& K0 Z5 G$ F/ M53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
, W* A, h0 x% N% U* ?9 C9 W54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
, h# D5 Y3 E E55 } /* end cycle */ 9 \+ V# B* L) J1 Z# U
56 out[0] = ntoh(y);
( P( `7 z8 R3 X7 u57 out[1] = ntoh(z); . h9 h S1 V0 C! @
58 }
: s0 ]0 ?& H( D2 A2 ? S* Q59 ! n0 x" T& s& O; t: m/ o2 W
60 void TEA::decrypt(const ulong *in, ulong *out) {
9 S- N" L& D7 X# s61
9 y- k. j8 p' h" f' ^62 ulong *k = (ulong*)_key;
* M3 d" y( ]3 V5 T( K/ _' {63 register ulong y = ntoh(in[0]); ; R$ ?5 Y/ ]3 a+ a: a
64 register ulong z = ntoh(in[1]);
3 Z2 d( o( q6 S" C% k65 register ulong a = ntoh(k[0]);
/ k& q# d; w( L# Y+ @! B* ^66 register ulong b = ntoh(k[1]);
/ p# ]8 x$ Z' n; D6 N; n. B+ k67 register ulong c = ntoh(k[2]); * F5 F# D' I$ }. E% v' n5 N
68 register ulong d = ntoh(k[3]); . c5 F9 Q) o/ h/ i+ h1 ]
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
3 ^' J6 p: A6 Z1 a* d8 n70 register int round = _round;
) U% q; Y" z p71 register ulong sum = 0; 8 }$ |5 Z( Y" a$ Y! ]5 d4 f
72
9 f; \( d! U# q l% a2 ^4 c73 if (round == 32)
# T) _, }- T( J% F3 w2 k74 sum = 0xC6EF3720; /* delta << 5*/ . C6 V' c: S3 k/ _8 n$ k0 y& _. ]1 h" f
75 else if (round == 16) 6 B' T" P. |6 ^ Z8 {0 T. v
76 sum = 0xE3779B90; /* delta << 4*/
% C4 H" @1 r) z% k3 m4 ?5 I77 else 1 ]1 h: N, W4 @1 d6 [& \& o
78 sum = delta << static_cast<int>(logbase(2, round)); ! ]" S! d1 L3 G) O4 H
79 - F3 B; B& n+ \
80 while (round--) { /* basic cycle start */ # ?4 S3 r; V* q& J( ~
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
4 K9 K5 p: G. X* y' t82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
# d" A# W# o* K1 v: r83 sum -= delta; ( L7 o6 g( l; L
84 } /* end cycle */ ( O$ H- I+ [, Q5 c3 v- @1 a- Y
85 out[0] = ntoh(y); : C$ e. @( O2 I* _# [% x0 R
86 out[1] = ntoh(z);
0 z8 |0 K: R" Z7 M+ r' }87 }
9 Z% F6 ~5 u5 i6 l! o5 M- C4 ^" y5 B4 H
需要说明的是TEA的构造函数: ( V+ X* o+ F6 |5 A
TEA(const byte *key, int round = 32, bool isNetByte = false); / N3 o4 P( q0 o$ H, J( H$ U6 c% [, @
1.key - 加密或解密用的128-bit(16byte)密钥。
! E8 s0 h' W$ f! A1 ]1 N7 W2.round - 加密或解密的轮数,常用的有64,32,16。
+ a) \7 `% @6 N+ t3 b2 y9 H2 u3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! ) p1 G, n) G }9 A8 x m) |
2 Z4 p M9 F% m( C J5 z最后当然少不了测试代码: |
|