|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" 5 l8 d; i1 }+ R3 e. j7 ?: f
2 #include <cstring> //for memcpy,memset
/ D; q) Y: o8 d$ E 3
. m8 ~& O, h) z" s4 g! Z! w 4 using namespace std;
5 P+ H' _# A4 W% Y) ~: {3 l 5
6 Q0 x9 k$ x! r$ A! B! ~5 M' B 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
! M6 k, O" s& H" A5 A- f, l 7 :_round(round)
% Z" y" ^( q, i+ N4 \ 8 ,_isNetByte(isNetByte) {
' f3 _1 h3 s9 {7 l6 y1 q5 S8 | 9 if (key != 0)
+ w2 @3 I' e3 `+ P& ]5 I10 memcpy(_key, key, 16); / G0 o1 Q) R9 J' p& P$ G% U) Z
11 else
/ u7 J7 E3 _" Y12 memset(_key, 0, 16);
* T9 \1 Y D& F; g& J% J13 }
# S0 Z. S# M/ y* Y/ a14
8 K. U7 I2 ]( ^15 TEA::TEA(const TEA &rhs) / A/ D0 v; ~* }
16 :_round(rhs._round)
0 X( Y+ q) ]4 N4 U; m* B: Y/ V17 ,_isNetByte(rhs._isNetByte) { * _& h6 F8 m) g, S2 h: L) L3 d3 t
18 memcpy(_key, rhs._key, 16);
/ a6 Z% f& N& [* T, b19 }
" M+ y* H8 S8 a5 @$ h Q9 X20 / a' T4 l% G7 Q2 b6 G
21 TEA& TEA::operator=(const TEA &rhs) { , i; Z9 f# h4 Z6 u' Y: R, s
22 if (&rhs != this) {
0 I/ y. v, P% F0 S3 j* k3 i23 _round = rhs._round; 9 \' s m$ i' K, [
24 _isNetByte = rhs._isNetByte; + w5 A8 {# i* F$ M$ v
25 memcpy(_key, rhs._key, 16);
7 F0 I$ B1 \9 R' k' p: j0 z0 G26 } ) e4 E+ F* z5 p3 W$ J: G0 s
27 return *this;
: k, i4 P* f- c8 [! r28 } 1 M& t6 o* \" ^ I ?- n6 T. Z
29 3 p$ R% i l4 Y
30 void TEA::encrypt(const byte *in, byte *out) { % g' D1 G! n2 w5 v; U6 r
31 encrypt((const ulong*)in, (ulong*)out);
/ a" V3 h' I9 X1 M" B9 ~32 } 7 ~! B% _8 p0 o6 c$ r! }$ g k! L6 V
33
# K; g' \7 G- w* ]/ A34 void TEA::decrypt(const byte *in, byte *out) {
5 Y. \. R$ H: m. p0 \3 A2 d35 decrypt((const ulong*)in, (ulong*)out);
* x; ~& R: _8 h1 C36 }
, s5 b1 A1 q b* q+ \7 h$ }37
. ~- c C* N; i2 c; S3 \38 void TEA::encrypt(const ulong *in, ulong *out) {
3 u# u* l1 p/ D; N# Z' f( B, ?39 % i: R2 I3 X* ^5 A
40 ulong *k = (ulong*)_key; 7 [" }, q4 p' h7 F0 O
41 register ulong y = ntoh(in[0]); ( k2 v$ }0 e S
42 register ulong z = ntoh(in[1]); 1 Z1 {& D' }; ]5 O( f2 F! {3 M0 v; W
43 register ulong a = ntoh(k[0]); ! ]% y: _- U! f( k$ w5 k
44 register ulong b = ntoh(k[1]);
; y) B- h, K4 W2 i* R45 register ulong c = ntoh(k[2]);
- p. V* e! B# {/ Y2 L- H: m46 register ulong d = ntoh(k[3]); 0 v& y8 i7 G! S! J
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ ; y4 a2 @; ^% ~
48 register int round = _round; ( h7 o4 Q. @# _6 P7 I' h
49 register ulong sum = 0; & q: g; e2 p1 o% R' P5 }# |
50
( ~) `* n$ y3 a. c% D z) O4 \ m51 while (round--) { /* basic cycle start */
5 M4 h% b" `9 v52 sum += delta;
- |; }7 J7 Y+ y53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); ! h3 [9 W- D, w+ U! l7 f
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); * c) B$ C4 N$ ?. b. n
55 } /* end cycle */
0 v7 j) L' C' w4 p6 O+ R+ v9 X56 out[0] = ntoh(y);
" i, ~( ~8 O: w# v3 g57 out[1] = ntoh(z); ]2 x: P0 D5 g5 T, T* F! ]% y
58 }
. f$ a/ \' `. E- P59 ( W w2 ^, Q1 ]3 g
60 void TEA::decrypt(const ulong *in, ulong *out) { $ b6 d$ r. p$ N2 I9 R
61
; [0 k N" a1 S7 `62 ulong *k = (ulong*)_key;
: y- x4 u7 E+ V7 u1 ]63 register ulong y = ntoh(in[0]);
4 X$ ^- X2 N7 [ c. r/ k% [64 register ulong z = ntoh(in[1]);
6 I0 o: W& Y- N' Z, l4 n65 register ulong a = ntoh(k[0]); 8 a/ Q/ B4 @/ ^1 h! k
66 register ulong b = ntoh(k[1]);
) n1 Z& Q# a2 ~- }" z+ v67 register ulong c = ntoh(k[2]); 4 e: I8 k/ _& R; O" o1 w7 y
68 register ulong d = ntoh(k[3]);
. E( _. Y. C6 z" C69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ , c1 Z1 A9 k( h3 _! Y, ]
70 register int round = _round;
3 U# h( w. z( z) m71 register ulong sum = 0;
8 b# b5 I1 ~4 u; A1 s9 l72 0 X- E" v6 g1 d5 P* n, s- C* E
73 if (round == 32) * Q( U5 q' g6 J0 v2 F
74 sum = 0xC6EF3720; /* delta << 5*/ 5 t P$ c1 ^% D
75 else if (round == 16) * X3 M$ h' v# |! A; s
76 sum = 0xE3779B90; /* delta << 4*/ 4 l2 f4 J6 Y# n$ D
77 else
. O4 p9 [8 _" F5 z78 sum = delta << static_cast<int>(logbase(2, round));
7 Y1 Q, {" \9 x) `, i79 5 N* c4 g& G6 r8 D: n2 O' p
80 while (round--) { /* basic cycle start */ & q$ f& A, l# `, o7 i0 j6 j; W
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
, L1 l% G; j9 Z+ w$ Q82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
0 B1 ?% A- A. O- _. E83 sum -= delta; / ]/ ?+ b1 j0 l- X' T; X
84 } /* end cycle */ ! \/ u* X9 H# f v
85 out[0] = ntoh(y); , c) U7 _* A4 g1 U2 O
86 out[1] = ntoh(z);
% y" h* {4 V! g! q87 }
& T7 m' u6 T+ s Z
. L+ s3 ]5 s/ M# V需要说明的是TEA的构造函数:
' J" \1 @2 r0 c' r6 _, O/ dTEA(const byte *key, int round = 32, bool isNetByte = false);
8 ^4 \, x: L* w1 b q9 J1.key - 加密或解密用的128-bit(16byte)密钥。 + K+ q W {3 X4 }3 G* M: C
2.round - 加密或解密的轮数,常用的有64,32,16。 ! C! `- z, B( h# O7 F5 b7 M
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! ' y3 }, u2 p7 K
" w( y! ?3 U8 `1 E# n: j. e最后当然少不了测试代码: |
|