|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" $ I: z& c( M+ Z& d. z# ?
2 #include <cstring> //for memcpy,memset
8 R9 c. @: ^/ W( ?; J0 j9 j( g' Z 3
, m8 v4 y$ |6 N 4 using namespace std; 0 g. H2 d/ y4 [' E* T) R% v: x
5
& H- y+ H. ^2 t# G% E# q 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
5 p! h8 ^3 a6 G H! { 7 :_round(round)
9 x( ?$ R: C& a3 o* q# s9 u 8 ,_isNetByte(isNetByte) { " a$ J3 U2 e, C; d4 V$ ?2 [9 E
9 if (key != 0)
' v& y8 |. p' n+ |% ?! c% z10 memcpy(_key, key, 16); + I5 w0 T' N; R/ v% s: V
11 else " d) x/ E; o2 F& _: K
12 memset(_key, 0, 16);
3 g7 p' R" ?% r5 _5 J13 } : ~6 P; Z; V' U: f, {3 Z
14
2 d6 D5 Z' H! Q15 TEA::TEA(const TEA &rhs)
' |: S1 q9 E0 J) F. c16 :_round(rhs._round)
0 _, y; V6 S3 Y* J% y17 ,_isNetByte(rhs._isNetByte) { $ [: C/ h, P3 U0 ? Z1 k
18 memcpy(_key, rhs._key, 16); + \( E% F* N9 y2 H2 q7 w0 z
19 }
* B5 P5 ]; u; O4 v2 W5 S20
2 _5 [* J& b5 g% N# ^' U7 X21 TEA& TEA::operator=(const TEA &rhs) {
& [' `6 ]0 S; z4 s& v22 if (&rhs != this) {
( y& P# r' K$ F1 q; v23 _round = rhs._round; 2 Z9 _) ?$ Z& M
24 _isNetByte = rhs._isNetByte;
, P5 Y, T1 z n6 j4 u25 memcpy(_key, rhs._key, 16); " M; n! U# a: g
26 }
* x9 V2 V: x, v, R, H9 F, U, W27 return *this; ( `9 H, o8 u Y. _( Q
28 } . s$ X$ G' y( J" V+ M* V' G
29
' u% I8 X1 q3 `30 void TEA::encrypt(const byte *in, byte *out) {
% }2 S7 D& y5 r4 g4 @3 n31 encrypt((const ulong*)in, (ulong*)out); + X {4 [( J: N8 z+ A
32 }
% [$ {4 m) d4 N, p33
' i8 l8 {; T+ Z! X34 void TEA::decrypt(const byte *in, byte *out) { : Y" S" w7 _* v; ^$ y! ^* }4 A
35 decrypt((const ulong*)in, (ulong*)out);
( |; M: f+ F5 i: L36 }
2 r7 _% z; y/ A1 G5 [5 {37 ! `8 o, _/ D$ M0 J
38 void TEA::encrypt(const ulong *in, ulong *out) { : B- m. c5 N6 g2 k$ w5 `
39 9 x" ~: D) y2 e
40 ulong *k = (ulong*)_key;
$ ^" W. }4 o3 v6 N$ l# V3 m9 _+ z" D8 E41 register ulong y = ntoh(in[0]);
8 d5 F2 b' A1 m$ W' X42 register ulong z = ntoh(in[1]);
% _( i+ @0 Q9 c2 Y43 register ulong a = ntoh(k[0]); & j, q$ v' a) q/ |- I
44 register ulong b = ntoh(k[1]);
9 c7 P& t; D6 I' S8 C45 register ulong c = ntoh(k[2]); ! C/ n: F+ r$ Q8 ]5 j4 K8 m- F
46 register ulong d = ntoh(k[3]); " Q9 k- v0 {2 m& g
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 1 K$ r. l- `' ^- n/ i& R) {% t5 p1 {
48 register int round = _round; 7 Z5 d! b' ^5 S# S
49 register ulong sum = 0;
* P+ C0 l% ?) q) U6 e. Z50
- V5 T4 v" M4 ?51 while (round--) { /* basic cycle start */
5 P' w! ?% F* _7 l1 [5 j( {52 sum += delta; , `/ i/ A7 A9 j( C0 M% k, k% Y
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); ) m& @. H% W9 b* S# s" w0 w
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); 2 S; J. Z& m4 y9 b7 \! I7 N
55 } /* end cycle */
0 M' m5 f; z/ L! S56 out[0] = ntoh(y);
9 \. `) x2 ?7 Z57 out[1] = ntoh(z); 0 G& [+ j% a8 a U; G; j: v
58 } 1 d, D* j/ X- l' {+ u" L
59 0 `' p, j' g+ O
60 void TEA::decrypt(const ulong *in, ulong *out) {
: Y& l$ f) F5 Q3 g5 U0 c61 % o' h9 y& c& ^3 y! c$ g" ~
62 ulong *k = (ulong*)_key;
4 N& v! m- Q, m. ] f7 [+ r63 register ulong y = ntoh(in[0]); ; A; o5 |1 O; V
64 register ulong z = ntoh(in[1]);
: G3 s9 q/ x8 n* Q; O: Z65 register ulong a = ntoh(k[0]);
$ D7 I; s& }2 P; j& E& p; ^66 register ulong b = ntoh(k[1]);
; J. B' J5 a% d( R& }67 register ulong c = ntoh(k[2]); 9 r8 d4 h1 t; Y9 H9 p5 B
68 register ulong d = ntoh(k[3]); $ Q3 M5 N0 ~9 ]+ ?
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ / m$ ~" @4 P" O3 u$ A. i
70 register int round = _round; : u1 [2 m) j; q: S; b
71 register ulong sum = 0;
0 ?! ^" D0 q. ?% _: L( s ~4 b72
2 Z1 W/ D1 c; ~2 a- v8 Y$ g73 if (round == 32)
1 d$ u! C6 m/ P4 U74 sum = 0xC6EF3720; /* delta << 5*/ ! l5 A5 T$ t1 a0 q5 u1 g
75 else if (round == 16) 1 _+ ]* v6 ^' x i4 t
76 sum = 0xE3779B90; /* delta << 4*/
! \: N$ p- k. Q77 else ; {. B3 Y+ U9 R: e* |: n
78 sum = delta << static_cast<int>(logbase(2, round)); & y/ D- G- N; K8 o4 Y- H
79 ( g: e2 o. z, X/ b% N
80 while (round--) { /* basic cycle start */ ' [1 i' ?( w4 U% S+ V) ]* h' D- M
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); & Q4 z2 C6 Q( P K5 ^7 L2 X
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
/ k+ t. ]% z- k& w83 sum -= delta; ) m1 s: R' J9 P* W+ ?& r+ |% r
84 } /* end cycle */ j: ~8 n P' X( j% P
85 out[0] = ntoh(y);
2 H3 Y0 \5 J ]5 U* T86 out[1] = ntoh(z); - m; c2 J/ | g& G2 E5 }# c
87 } M% `4 X& J% d4 K
; o/ \% [0 Q( r7 E
需要说明的是TEA的构造函数: 8 n% j4 p _* T5 `, T" Q6 {
TEA(const byte *key, int round = 32, bool isNetByte = false); 7 V9 D1 P8 _/ o: R& O3 ~
1.key - 加密或解密用的128-bit(16byte)密钥。
, I; ]' G- A; V4 I5 k5 \/ G: c( L6 H2.round - 加密或解密的轮数,常用的有64,32,16。
* g/ r, y! H) f3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
- c$ B5 G, u" f9 d/ M$ ^6 w
' z/ W; N( p- }* B: X$ A0 n最后当然少不了测试代码: |
|