|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" 9 f ]4 l# W P% \5 {
2 #include <cstring> //for memcpy,memset . }2 P/ k3 P- K: J& S
3
' z2 \: A F( B1 W$ d. ?& | 4 using namespace std; ; }, S( \5 S* J. e1 ~
5 ; Z4 D& d5 B) u) W9 K
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) ' a. s' ]( }$ g
7 :_round(round)
8 |& w3 v1 F2 g 8 ,_isNetByte(isNetByte) {
& w# D! b! x3 b0 M d4 N3 [ 9 if (key != 0)
' C. @$ m" `& M4 R10 memcpy(_key, key, 16); 1 t* i4 Q# q) w% r" I' a3 y
11 else 8 c' O2 x( c! u6 N5 Z( T- K( V
12 memset(_key, 0, 16); 0 |$ C% L8 M+ b0 K7 ] W y" X# L9 g
13 } 3 x& v$ S x" }) q
14 ( V; H+ ^, i7 b: u+ b! m
15 TEA::TEA(const TEA &rhs)
; M5 z+ m7 q! ]$ u& t* \7 f& Y16 :_round(rhs._round) # c$ h, ^% P' G1 V! _2 @- Y2 m
17 ,_isNetByte(rhs._isNetByte) {
, i, ]6 ~ m; ^+ z) Q18 memcpy(_key, rhs._key, 16);
$ M" \" G! N- ~; ]( Q1 H19 }
5 F2 ?# [! D; {% N8 ]7 I20
* C8 ]) ?; o- J21 TEA& TEA::operator=(const TEA &rhs) {
: m/ Q$ A2 k* m22 if (&rhs != this) { 5 g8 p+ w W% D# s3 d
23 _round = rhs._round;
+ u- S+ M: X3 N& f* U24 _isNetByte = rhs._isNetByte; 1 F0 {' @! Q9 K. A8 l! E- x! G
25 memcpy(_key, rhs._key, 16); . Q+ P, h" q9 O, A8 T5 M5 p
26 } " T; o. j# R0 [
27 return *this; / u7 \& }7 N) R- J" K& f w7 D* d+ K y
28 } $ e n5 G* b0 F: j' M6 p
29 5 ?5 W+ e- l- o, W" U
30 void TEA::encrypt(const byte *in, byte *out) {
- s" l) N1 F. [5 S# s31 encrypt((const ulong*)in, (ulong*)out); % }/ f) f \, w( W* f! x
32 }
5 t" [" J2 W" M: c3 }33 * L+ n C4 l; r1 x
34 void TEA::decrypt(const byte *in, byte *out) { ' b" \/ ~. |7 `3 W
35 decrypt((const ulong*)in, (ulong*)out);
: ?- x0 H+ N% ?" I" {36 }
- z7 a- k2 N) q; h/ O# t37
9 X' X( x) [" C2 c& A$ m38 void TEA::encrypt(const ulong *in, ulong *out) {
; n& U" D5 J. c) |39
; B' P! N1 X3 N. G40 ulong *k = (ulong*)_key; % j; X: a, W, h
41 register ulong y = ntoh(in[0]); ' i H6 u; W6 a
42 register ulong z = ntoh(in[1]);
" Q; e2 D) _9 j3 ~43 register ulong a = ntoh(k[0]); . e2 _8 v* G+ v9 P( }' i
44 register ulong b = ntoh(k[1]); ( G" ^0 v, e$ F. S: w
45 register ulong c = ntoh(k[2]); % y4 e, m8 U; r) C
46 register ulong d = ntoh(k[3]); 1 z& }, D6 [+ \; U4 A
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 0 ^7 k, L) W& B9 H9 F
48 register int round = _round; ' P9 w5 K" q$ L' b% H- _. e+ W
49 register ulong sum = 0;
! L' A" \8 c2 ^2 X2 V50
; @0 t9 D9 d$ P% H+ M% N51 while (round--) { /* basic cycle start */
, u3 K$ ]4 c+ j/ P6 H52 sum += delta; # [. ?$ Q! W2 x" P0 V" b( a8 |
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); 9 ]. u4 |2 z1 w0 L) \
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
7 _/ E+ n# D9 t+ T0 w55 } /* end cycle */ 0 K9 w F- L, f
56 out[0] = ntoh(y);
) N% B. ^9 i0 n, r3 j# _) A57 out[1] = ntoh(z);
& z0 G8 w: H' V3 _, [58 } . l8 `4 n# J$ o) h6 O+ X
59
; w; e. h( @. E* b4 y60 void TEA::decrypt(const ulong *in, ulong *out) {
8 M9 S0 A j! g8 s0 y _61 / C$ D% w f1 e9 G+ E* _
62 ulong *k = (ulong*)_key;
: r0 A8 e% ^9 B) U h1 q' L63 register ulong y = ntoh(in[0]); 9 H1 \! b" I2 \) r. T
64 register ulong z = ntoh(in[1]); o4 M! Y) X' H: ~: x
65 register ulong a = ntoh(k[0]);
1 `5 U( X& k1 G& [ o- D7 {; }66 register ulong b = ntoh(k[1]);
) K6 R! n _1 M" f67 register ulong c = ntoh(k[2]);
z1 K- M' g- P: [) i68 register ulong d = ntoh(k[3]);
! `( R e$ g t5 m6 t* H' d69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ ) X0 G9 U& j$ Q- t; Z
70 register int round = _round; 5 @9 B3 a' o- b3 L
71 register ulong sum = 0; 2 b6 G: i1 U/ F/ V- Q
72
1 V1 `' M+ |2 K8 R3 T73 if (round == 32)
6 I: h$ G0 e. K/ V74 sum = 0xC6EF3720; /* delta << 5*/
* S3 T, ]& P+ O7 }75 else if (round == 16)
. b4 c' [3 @+ j5 A2 o& |( X. R% ]9 j76 sum = 0xE3779B90; /* delta << 4*/ , @/ @% B! H; Q. V. [
77 else . L. l* h; c1 {
78 sum = delta << static_cast<int>(logbase(2, round)); 2 Z ~2 S" t1 b3 {
79 }' ~# |: G8 U6 t8 }9 V) U. s
80 while (round--) { /* basic cycle start */ & m, f/ n- ^4 r/ h7 T4 K
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); 1 |: ~7 i4 @' ?& ]2 S. Q' }! d2 x
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
) S) w/ c9 u8 L( Y6 y6 n83 sum -= delta;
9 |/ C& F- S+ n. R84 } /* end cycle */
- m. Y. \/ M `+ I2 \1 G85 out[0] = ntoh(y);
9 J5 [! r, C: G8 I9 g' v: M2 R& A86 out[1] = ntoh(z);
% w* B# q6 z! b2 F% X7 s2 G! P) c87 }
0 W5 ? P- A! ]0 b. O5 `0 ]# S2 c% u, z6 q
需要说明的是TEA的构造函数:
; n) J3 R9 W2 Y( qTEA(const byte *key, int round = 32, bool isNetByte = false);
& O# S: I6 |$ q* L3 r1.key - 加密或解密用的128-bit(16byte)密钥。 ; m1 ?0 r/ W5 ]0 W# `- c
2.round - 加密或解密的轮数,常用的有64,32,16。 5 d5 I/ f! `" A6 x
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! $ g/ l/ E5 _7 z2 l
- q* {0 U9 S6 H- x/ Z% `最后当然少不了测试代码: |
|