|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" 7 B' ~9 Y0 X# i9 w
2 #include <cstring> //for memcpy,memset
7 \% {2 d: {1 X8 `0 a( o 3
2 Q" y5 H1 N% \5 ]9 O% B6 i 4 using namespace std; 5 Z) \* k' Y5 C7 F' A4 @0 W
5
6 I: s* h* n" ^0 f+ ?9 J3 T1 o 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) 0 r+ o0 \* z' @9 f6 D7 k* H9 w
7 :_round(round) # K5 z/ @& |" ^" {. v, n
8 ,_isNetByte(isNetByte) { $ O& H3 K/ x$ q Y: E( K
9 if (key != 0)
7 E$ C5 r, ~$ a3 I+ {10 memcpy(_key, key, 16);
2 T2 B; J6 S( H9 |, e+ ?11 else . O3 s+ Y- z/ P h# K
12 memset(_key, 0, 16); % N$ F1 A& |5 Q
13 } - j0 H, {0 O! M W
14 - j5 t! N% H8 x; S5 I3 Z1 V& m
15 TEA::TEA(const TEA &rhs)
- z* ]) K8 ?' ?, r3 i8 N16 :_round(rhs._round)
# n/ e/ B/ L' F. G" L0 X17 ,_isNetByte(rhs._isNetByte) { - m* |, ?0 V) G. f1 ^
18 memcpy(_key, rhs._key, 16); + P- V" i/ H, A1 N; y
19 } ) ~( F6 L2 T6 ^
20
8 J2 S0 P2 p/ B# Q6 Z* x: g0 J1 N! ?21 TEA& TEA::operator=(const TEA &rhs) {
+ M3 V- s8 x4 e22 if (&rhs != this) {
0 G2 |# m7 j# Q. l23 _round = rhs._round;
8 a$ T) e4 j& B; c4 o24 _isNetByte = rhs._isNetByte; % ]& o& N) R2 j
25 memcpy(_key, rhs._key, 16); 9 k& J. S) {& h. o
26 }
- n" D$ p3 c* {) i7 s7 T27 return *this; % |6 i5 E# D( R; G& u% V
28 } 9 v7 v: h% g- E& h% a) V: c
29
4 g6 s. u- V9 H# a/ n( r30 void TEA::encrypt(const byte *in, byte *out) {
4 `+ X9 N: M/ X1 @) I- _; I! V3 S31 encrypt((const ulong*)in, (ulong*)out); 9 ^. R( r0 Z A8 {4 k
32 } # H, i! ~/ O- ~/ N2 |3 E
33
0 @' |( c2 {7 [ N* g- t' i34 void TEA::decrypt(const byte *in, byte *out) {
3 X0 O7 D4 O3 h7 K6 J35 decrypt((const ulong*)in, (ulong*)out); 6 Z5 \4 O% g$ l, c, t9 E9 b+ u
36 }
) R% X0 d! r9 T0 ~1 s37 , s; n J6 K o4 h
38 void TEA::encrypt(const ulong *in, ulong *out) {
; M0 t' W$ U! f39
& n! ]2 \- m: [& T4 N40 ulong *k = (ulong*)_key; - x& q P3 W4 c( R4 [
41 register ulong y = ntoh(in[0]);
* D1 H2 X2 g+ Q( w42 register ulong z = ntoh(in[1]);
+ a( E4 l( R6 M* K; Q7 r43 register ulong a = ntoh(k[0]); U7 T; |1 F! O* s. o( B& s' |
44 register ulong b = ntoh(k[1]); ' C/ J, o6 o3 ~7 V5 N: e
45 register ulong c = ntoh(k[2]);
% b. C1 Z4 E# r( W46 register ulong d = ntoh(k[3]); ; l* B" g& M* F+ b' ?
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
( N x# r; q3 u48 register int round = _round; 9 G/ T7 q% P! i' [0 c& T( h: F3 M! w
49 register ulong sum = 0; . ^! }8 R: D0 Q. I
50 $ T; b4 |! M9 z1 `
51 while (round--) { /* basic cycle start */
" ^# m: k7 Z# Q. B7 y52 sum += delta; 0 Z; J N: _% _6 {( Y
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); " ]; Q: S& c+ E3 E
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
! \; B- t" @1 r3 N) I) ?% @55 } /* end cycle */
7 Y8 k" k2 M" S9 r3 z56 out[0] = ntoh(y);
) \2 O7 `/ Q- N$ T9 ?! E: Y1 L57 out[1] = ntoh(z); ) V7 E1 p/ i" \0 f8 C9 i
58 }
1 m; E( C [5 x! K: \! T) p4 I59 , g8 ~$ h/ y. o1 B) N, ?
60 void TEA::decrypt(const ulong *in, ulong *out) {
, ?6 P# a, f, |4 t61 5 B( L& y& h5 l- a& `& k9 \
62 ulong *k = (ulong*)_key; % ]3 a& g, m, x) ~
63 register ulong y = ntoh(in[0]); 3 O: t) S" B# h0 F/ f
64 register ulong z = ntoh(in[1]); 6 k) x7 i; m/ l9 o
65 register ulong a = ntoh(k[0]);
# C. t4 T- J, W8 U* |66 register ulong b = ntoh(k[1]); 9 n% Z- T! I2 v* ~& v% R* x
67 register ulong c = ntoh(k[2]); ! C$ l0 z& `9 r1 x# F
68 register ulong d = ntoh(k[3]); 4 v# @6 j" N, j
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ ! p# t( h2 S T. g
70 register int round = _round;
4 I* U/ ]- o, r71 register ulong sum = 0; ( I& a% u2 R( h/ C$ n
72 2 i5 d b' J( f# @* w
73 if (round == 32)
* ^3 q+ v; n( Y7 O' x6 C74 sum = 0xC6EF3720; /* delta << 5*/ ~7 i1 R8 e2 w: _4 {5 j7 f/ B E
75 else if (round == 16) ( i' T% z7 x: s& S2 C6 R0 v' I
76 sum = 0xE3779B90; /* delta << 4*/
9 d" p# v2 t" h2 y5 I) g; E/ N77 else + k+ ~: |4 W1 x! \2 W9 i, ~4 g
78 sum = delta << static_cast<int>(logbase(2, round));
8 x: s: \0 ^" p79 + i- d3 }! o8 @5 \6 x
80 while (round--) { /* basic cycle start */
9 C+ P: w x- I: f" j6 m81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
" q( H" J0 e- B R82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); ) ~" } T; r2 N# ]* K/ l
83 sum -= delta; . [3 E# O1 U( a$ g. N8 V
84 } /* end cycle */
. C3 T9 N$ E5 J5 x$ t0 }/ Z5 h85 out[0] = ntoh(y); ( E, t1 W9 i# k% c8 n
86 out[1] = ntoh(z);
, r- |+ F5 a |* G2 M87 }: B, i& W9 y( v4 K
. ]2 z9 a( l; l- i" G, \
需要说明的是TEA的构造函数:
/ B8 w! \4 C, |( i1 t) d8 L7 t8 iTEA(const byte *key, int round = 32, bool isNetByte = false);
* W& W6 |' F" d/ `" r G' O7 |* o8 i1.key - 加密或解密用的128-bit(16byte)密钥。 8 l; \& O6 k3 c# y. X! `3 e1 y
2.round - 加密或解密的轮数,常用的有64,32,16。
) w$ D2 s6 _& \$ q( R3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
& f$ {6 ?# e0 R
0 d+ l. |+ p. d最后当然少不了测试代码: |
|