|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" * X9 s4 {2 {: D
2 #include <cstring> //for memcpy,memset
, c9 }% h6 s* c& S% h# E 3
$ j4 l: z6 Z; }' a- z& {; a5 C 4 using namespace std; ' J" i( A, E& e$ q2 a( J6 j) I1 b
5
7 s7 b# ^7 N. P" S 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
( F B0 z" T* i+ \2 T/ P 7 :_round(round) / @% z& I9 [: q9 i7 `7 j- L. l) c
8 ,_isNetByte(isNetByte) { " s& K* i% x# D' A. q
9 if (key != 0)
7 U2 L6 K, _- {5 E' @8 K8 c10 memcpy(_key, key, 16); : G7 Z- _$ J: E
11 else 5 Q0 i0 W5 v4 L& I5 X
12 memset(_key, 0, 16);
' L/ w; B$ s: Y7 R13 } , U; I+ E' M* ^
14
' X. |5 d; r) m* u15 TEA::TEA(const TEA &rhs) 6 M9 a) [' e: H/ ?, k$ Z( I
16 :_round(rhs._round)
# v$ F6 G- [. f, T9 k/ }17 ,_isNetByte(rhs._isNetByte) {
7 |' ]! x7 B- M+ _7 C" k$ V18 memcpy(_key, rhs._key, 16); ; m U* K- T: G
19 }
! v1 j8 B" q P Q) C& i+ w/ q20 6 ^. |3 U) i) y u6 E
21 TEA& TEA::operator=(const TEA &rhs) { 7 u9 _5 I+ n( z( R
22 if (&rhs != this) { 9 D, |+ T% f! B# S
23 _round = rhs._round;
, l8 w4 l, }( o# W1 L9 n7 _# M24 _isNetByte = rhs._isNetByte;
/ { |) o) Z8 P. s6 ~" n25 memcpy(_key, rhs._key, 16);
1 d I7 s9 m" E26 }
% x: Q( E& {5 H+ v27 return *this; C4 D3 P# r/ c0 H. o3 z
28 } * l8 T c+ a7 a c) _0 S8 }! U: Q
29 6 [: W6 H& o4 M7 Y- |& u$ Z6 [
30 void TEA::encrypt(const byte *in, byte *out) {
( s. h) r. a+ X' q" s/ O8 n31 encrypt((const ulong*)in, (ulong*)out); 3 i0 }) S0 d; B/ _% W
32 } 2 T7 h! C. ^) B2 _
33
0 }* ?3 I& _4 @8 z34 void TEA::decrypt(const byte *in, byte *out) {
V1 q! B; ^8 h# B2 z35 decrypt((const ulong*)in, (ulong*)out); * n3 D7 v- ]6 Y% S. R
36 } 8 D |1 w1 v- E5 Z" i4 k9 }0 Y
37 - P5 M) F) O$ s# }3 W8 ?
38 void TEA::encrypt(const ulong *in, ulong *out) {
+ {0 W% p' r% {1 Z) O9 p1 y39 ( t, A; h9 `% R$ O- w
40 ulong *k = (ulong*)_key;
7 S: H- G: D) e' C41 register ulong y = ntoh(in[0]); 3 _ G" P% P' c
42 register ulong z = ntoh(in[1]);
$ Q" v) e* @6 s0 ~8 F! P- e& d3 e43 register ulong a = ntoh(k[0]); ' D! p% Z& _/ C- @
44 register ulong b = ntoh(k[1]); ' b/ Z" I) J6 h! I
45 register ulong c = ntoh(k[2]);
+ x6 K+ C. b( w3 e46 register ulong d = ntoh(k[3]); Z8 Z1 G3 R! Z1 b: X* Q
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
/ v0 X7 B+ r/ L& e$ I7 Z48 register int round = _round; ' r" i+ n6 [, S3 b {- r& I
49 register ulong sum = 0; # b2 }( [% r9 \" V/ H9 @% W# [4 t
50 7 C T7 v7 @4 t* Z" I, `3 m/ h
51 while (round--) { /* basic cycle start */ 0 w( ~9 j' x! t
52 sum += delta;
, T z" _) J. x) O% E; o; }5 k53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
k" q$ E# M, |" X+ s0 M% m$ K54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); . t( C- B4 l7 Z5 i. b
55 } /* end cycle */ $ h. a1 A1 {4 R, m6 ?
56 out[0] = ntoh(y);
4 `( [2 j4 s/ \" Z3 O2 G57 out[1] = ntoh(z); 6 k8 G8 J- `6 t) \, L
58 }
: L) v3 D7 _" o4 `59 % E- w o% Y0 a( z7 Z
60 void TEA::decrypt(const ulong *in, ulong *out) {
8 _5 w- ], l$ ^+ m" X' Q61 % I7 J9 ^3 C3 W5 {( `$ z
62 ulong *k = (ulong*)_key;
+ E, E0 o/ l* n. n4 Q63 register ulong y = ntoh(in[0]); 6 Z8 P, s8 o+ f1 A$ n
64 register ulong z = ntoh(in[1]); / s r9 d+ n5 _6 I1 u
65 register ulong a = ntoh(k[0]); y, R: L7 I$ W0 |0 A& M4 Z! w
66 register ulong b = ntoh(k[1]);
& M0 _$ I4 R; H2 Z8 i/ a67 register ulong c = ntoh(k[2]);
7 D0 U* |, J: g& s u$ J! S68 register ulong d = ntoh(k[3]);
1 F5 k* d/ L6 x% w: ^9 K69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ ( b0 i+ v* ^. {0 @2 N
70 register int round = _round;
/ T, \- M, B5 l: R S& K9 R5 F* s1 L71 register ulong sum = 0; ( U6 ?0 ^+ [, d; o' m4 w, }- l
72
( x! H( T' y6 y7 b( Z4 a73 if (round == 32) , X) @# X+ [" t$ ~3 ~
74 sum = 0xC6EF3720; /* delta << 5*/ & B8 \4 r+ R1 X" r! m) f$ D+ U
75 else if (round == 16)
7 U2 F C9 j/ Z$ e3 q- F76 sum = 0xE3779B90; /* delta << 4*/
5 F% @9 h# D0 g* z5 K77 else
+ q y) l1 o; k4 }78 sum = delta << static_cast<int>(logbase(2, round));
$ E' V2 M, Y4 @+ L3 @79
2 P. a9 B4 r* Y) H4 b7 d80 while (round--) { /* basic cycle start */
! H8 [/ g" e" |( n81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
$ N* }$ E' e4 _7 c3 e1 y82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
7 D/ r" n! D5 ~/ F3 n83 sum -= delta;
6 N6 v$ |$ B. g* X0 W& C84 } /* end cycle */
+ y3 P7 T1 {- p* z85 out[0] = ntoh(y); 0 \ |* s1 Y6 A* J; C. \
86 out[1] = ntoh(z); , M! Y) V# Y& o1 v# [$ A8 J) l+ ~
87 }
! s4 w& {( A! y
, Z# D- J& i3 r需要说明的是TEA的构造函数:
% b0 g' A; F2 H7 A2 zTEA(const byte *key, int round = 32, bool isNetByte = false);
; y$ g7 ^. U$ k7 f5 W# }; }# C1.key - 加密或解密用的128-bit(16byte)密钥。 " }. A8 e7 _3 p7 h$ P) a
2.round - 加密或解密的轮数,常用的有64,32,16。 ! \. \7 c9 H. T* a5 f! _+ [
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! 5 Y7 D5 U2 {- H8 e9 Q% V/ B5 E
X; @' c6 j* a$ F( M# \$ s, |
最后当然少不了测试代码: |
|