|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" ( R) p% f7 ^! S8 A. e$ m
2 #include <cstring> //for memcpy,memset
; S1 C/ c1 |! e/ X% }4 Y 3 4 O0 M5 S, D. A; w3 c
4 using namespace std; _5 j1 Y' r' A) @8 L
5
- i0 n$ C8 P5 q8 ?" B8 Q9 |' j* S& u/ U 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) 1 \; q# [0 u, }6 ]2 g+ W
7 :_round(round)
& t; D' Y5 `* T$ _" |6 b( E9 h- { 8 ,_isNetByte(isNetByte) {
: y" q% O+ G% t' \- P2 e 9 if (key != 0) 7 q8 i$ V# K! J7 W2 h x
10 memcpy(_key, key, 16); ! z6 T' q& ^% [
11 else
$ D/ Y5 H! y0 r" A3 a, I: P& F+ ]12 memset(_key, 0, 16); 1 m& M0 L4 \; W2 k/ ]; g
13 }
& m# t7 [3 U" { l+ F9 B# d3 _ T14
$ X6 X' h* S n/ W% z15 TEA::TEA(const TEA &rhs)
8 Z/ ]8 _" y g! p* N; h( Q16 :_round(rhs._round)
9 t: j6 }& x( E) ]+ i3 Q17 ,_isNetByte(rhs._isNetByte) {
: ~6 b0 z1 H( _4 f1 S0 C. j18 memcpy(_key, rhs._key, 16);
. Y7 d! l! Z0 a/ y- }' t19 }
3 t; Y4 {" x' y& n) V# N20 7 k& ^0 t. G' _$ z" z% a$ L/ n
21 TEA& TEA::operator=(const TEA &rhs) {
1 y: @9 k& n2 v: h0 O6 h22 if (&rhs != this) {
8 }0 P; n3 V$ @( t( x; f% ?6 Z+ f23 _round = rhs._round;
% u% ~+ v! r; K24 _isNetByte = rhs._isNetByte;
" M* A/ {9 z$ h' t$ l4 K) L25 memcpy(_key, rhs._key, 16);
8 F4 o* k) t+ V* k0 Q26 }
, Q4 j4 V( J9 b7 N; ~27 return *this;
! y( v1 c" m7 v U% b28 }
3 W0 u. P K* m" Y; p7 K29 : H7 f: R8 Y/ c$ y
30 void TEA::encrypt(const byte *in, byte *out) {
" R1 f2 c+ Q+ \5 b, R/ g% \0 a31 encrypt((const ulong*)in, (ulong*)out); . x c5 y0 K$ X0 t# @! ]
32 }
+ p+ Y) c* _7 Z, j0 Y3 d9 }33
$ X5 g5 P$ r5 ~' V; @' Q( l/ {; w34 void TEA::decrypt(const byte *in, byte *out) {
8 w) }4 b e1 r) n9 m35 decrypt((const ulong*)in, (ulong*)out); ) R; V# s7 @( X: ]4 ~5 L* K- e
36 }
$ J! I/ {9 C& v37
6 G5 R4 w9 }; _% W5 L) ?. I38 void TEA::encrypt(const ulong *in, ulong *out) {
5 m# x. w+ A' R, G6 k$ Q+ ^8 _6 R- m39
) O6 x2 `8 Z& y/ R* Z6 J40 ulong *k = (ulong*)_key;
2 X0 P# ~3 n0 [% t( r: j) }41 register ulong y = ntoh(in[0]); ) _* k* v0 w. l* g/ V
42 register ulong z = ntoh(in[1]);
# f$ ?: L0 m) J+ y43 register ulong a = ntoh(k[0]);
: y1 Z9 |9 o* ?9 e& e& e0 P I% S44 register ulong b = ntoh(k[1]); . e: X) u$ @, y
45 register ulong c = ntoh(k[2]); 6 i" U7 d2 X# x- ]% i s) v
46 register ulong d = ntoh(k[3]); 0 g; a9 C' Y# Q3 z+ X! h5 ~
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
% z# N. k$ k: b( H/ J0 R0 h48 register int round = _round;
9 C/ v* f$ f: R* A4 ?$ V49 register ulong sum = 0; - m$ B* x$ b* m' g) a' @
50 : L1 D' W! F. o* o+ E7 l8 l4 d
51 while (round--) { /* basic cycle start */ 2 q D. R- k, ^$ c( C
52 sum += delta; - L5 v( j8 p, ^7 G; k- ~! R: ^
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); 4 z; |+ h7 ?* D3 \# s3 i
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
- _; F" x8 g1 c' b% | Q55 } /* end cycle */ 0 v' U2 w! [8 \/ G% h2 T
56 out[0] = ntoh(y); . ?" O+ K$ T3 i
57 out[1] = ntoh(z); 2 Q8 [' Y) x# p3 [. R
58 } ) b, u. ] h4 p7 ]1 N! f0 k
59 , h' i+ s4 l+ h' Q9 `+ Q, j4 U
60 void TEA::decrypt(const ulong *in, ulong *out) {
8 N$ o) J, Q7 o1 l% q2 o0 `61
( q% t/ e3 ?* K# q) X62 ulong *k = (ulong*)_key;
) W9 T$ V- r; }6 Y6 e5 `; S/ M63 register ulong y = ntoh(in[0]);
. i' }! H3 d! F# d2 ], g1 R8 ^+ E, ]64 register ulong z = ntoh(in[1]);
& V+ Z0 A# o: ]( R: Y4 E65 register ulong a = ntoh(k[0]);
' u+ P7 s0 C5 o66 register ulong b = ntoh(k[1]); 8 {4 F- o" f" V l
67 register ulong c = ntoh(k[2]); % o- v2 W# w/ |; B ^
68 register ulong d = ntoh(k[3]);
, _" `1 Q" f( l69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ # X0 C2 q* E& k( j* g) @! F5 F
70 register int round = _round;
; U2 }" e; w" ?9 e71 register ulong sum = 0;
6 Y+ G& d5 {: L7 k2 D2 M( d8 R72 # Q: p' S0 Z' F# H" K4 J$ ^
73 if (round == 32)
. C+ |1 i* z1 u- G9 x74 sum = 0xC6EF3720; /* delta << 5*/ 2 F, m; E; o' g- [; H
75 else if (round == 16) ! v1 }* Y" T0 f( `
76 sum = 0xE3779B90; /* delta << 4*/
& ~% u# g+ X% ^, i2 @* H77 else
: F" _2 @1 d9 s9 ~+ j6 |78 sum = delta << static_cast<int>(logbase(2, round));
& W5 L3 R& g1 s3 Z4 G; C: r' W& h& H79
6 h. A, Z& V1 Q: _$ A0 G3 d$ G80 while (round--) { /* basic cycle start */
2 o$ G/ ?4 [2 S9 L% E+ f1 O81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
! o* x- i0 s; b7 R8 u7 T82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
' G G! Z" d+ Y" b, j) _, k$ k83 sum -= delta; * z7 K* T* J" @2 [9 v! Y
84 } /* end cycle */ 5 F: f1 b0 S* t5 W. E* C& o
85 out[0] = ntoh(y); 4 I' \9 H: @( F) O$ n0 Y' R
86 out[1] = ntoh(z);
( u4 n. W1 ~% B& [' d. K( `2 O- @: X6 W' P87 }; N9 M% y2 z g" L+ s, u8 ~6 E% |
6 d0 n; w3 o0 m/ I
需要说明的是TEA的构造函数: 0 m- J1 g: G, n& }
TEA(const byte *key, int round = 32, bool isNetByte = false);
; `8 L- J, d, F- e: L& a1.key - 加密或解密用的128-bit(16byte)密钥。 ) \0 O# { m' T# Q
2.round - 加密或解密的轮数,常用的有64,32,16。 ; M3 J, z @5 Q8 ]# z5 _2 r( r
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
- M8 Q7 `, N& I9 a C& F
3 }; n# U0 ]) ?最后当然少不了测试代码: |
|