|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" $ z) _8 }. F( x7 L
2 #include <cstring> //for memcpy,memset : l9 F9 }- n% l1 w$ G/ U
3 u: O0 \4 ]7 w. G( h; f
4 using namespace std;
8 O7 o1 `; b" P5 d; w 5
8 g% d3 `$ ~3 [) ~: y 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
|! X4 S! ]7 R a! [ 7 :_round(round) / H% [2 L- E9 `
8 ,_isNetByte(isNetByte) { , E: |3 n& u4 t/ s& Z5 y/ S
9 if (key != 0) 4 k0 s8 Z* `: Z3 j# ~) v
10 memcpy(_key, key, 16);
4 f; X* s q4 N( T# Q11 else
. R/ w. L! e: h: w# ~12 memset(_key, 0, 16);
+ M6 b% b! Z0 L# j; f13 }
( e: @* j9 u- B14
$ O8 x2 W; A9 ]15 TEA::TEA(const TEA &rhs) # o# |# I3 [% u0 v6 b
16 :_round(rhs._round)
% h' D F* Y' k& d; Z4 Q; G( d# d2 r17 ,_isNetByte(rhs._isNetByte) {
, [1 x+ Y1 n9 p t18 memcpy(_key, rhs._key, 16); 9 B& W9 x, o, B1 i+ @6 r6 C
19 } 4 t* O! n! q/ |2 y3 x
20 6 H6 J7 p' k$ d. k7 e8 \
21 TEA& TEA::operator=(const TEA &rhs) {
; `6 _' d; q, N$ ?8 L6 J" Y22 if (&rhs != this) {
4 P9 g4 i0 w/ M9 w/ I0 {23 _round = rhs._round;
6 y* z X$ W) C; P' X+ `( ?' _0 L5 @1 w24 _isNetByte = rhs._isNetByte; . W" D$ v: J9 P# m
25 memcpy(_key, rhs._key, 16); 1 N" | l6 @ X# G
26 }
1 l, L( ?9 k) c- C27 return *this;
& k* G2 W4 D8 l7 A- O: d7 R28 } ?* A/ [0 U S/ W+ |
29
2 _6 \" {2 @ F30 void TEA::encrypt(const byte *in, byte *out) { 2 q! k- F& T% S8 v
31 encrypt((const ulong*)in, (ulong*)out);
% H6 [$ ?5 {) v" r2 ~, k32 }
& E8 m4 Q+ T# P5 z1 s33 ; c# z1 _& a. e& e0 L' x& c* L
34 void TEA::decrypt(const byte *in, byte *out) {
% [9 b$ `/ I* E+ X( ~5 W3 Y. |35 decrypt((const ulong*)in, (ulong*)out); ; H" D: e4 V I
36 } ( o3 Q& V- X6 d! ^) P! v' ~
37
& W& N' O) @& `% j0 _ _9 t! N2 j& b38 void TEA::encrypt(const ulong *in, ulong *out) {
, E" O7 Q# L) q5 @39
[: l6 \( T$ E3 K* Y z4 E40 ulong *k = (ulong*)_key; & ] z% s: ?* y z* u
41 register ulong y = ntoh(in[0]);
- F/ m$ i3 z w0 O2 y42 register ulong z = ntoh(in[1]);
" O1 M- a6 X8 r43 register ulong a = ntoh(k[0]); 6 V3 @. A% |8 s" u, A% L& i
44 register ulong b = ntoh(k[1]); 8 `8 m# o& m' K; y6 o
45 register ulong c = ntoh(k[2]);
' t5 }: B9 P+ u46 register ulong d = ntoh(k[3]); / G& v3 E) z. c% j! u2 z: e
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 1 n4 r" \- w U: s- y/ K- Z) A
48 register int round = _round; - H7 J* I8 E3 `- M
49 register ulong sum = 0;
4 }! p: r1 {4 Y. [. s, J- R/ a50
% V. z w, e4 y# J7 e51 while (round--) { /* basic cycle start */
# Q. m# ]* W9 _1 H g52 sum += delta;
5 A/ n5 N3 o2 g$ f" G9 X& w53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); 1 [$ s( I0 x9 L3 z7 X
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); 8 b+ p! X- K" R( H
55 } /* end cycle */
* u h0 S! o% r8 K% O$ b56 out[0] = ntoh(y); 4 k" J/ R9 V; W
57 out[1] = ntoh(z); & x6 q9 T- B. o& F% ^+ X
58 } 5 \1 Z/ ^( p( S" r
59
3 k5 H, @ }" l- A+ K8 l' }60 void TEA::decrypt(const ulong *in, ulong *out) {
8 b( A1 I9 G5 ^8 u$ ?7 ]$ u61
2 E8 L# L; Q& b62 ulong *k = (ulong*)_key; + u$ H. `) ^* z& F) H) j
63 register ulong y = ntoh(in[0]); $ ` Y! g5 a L- k2 g" T
64 register ulong z = ntoh(in[1]); , W' o" Y4 R& @1 }6 n: t
65 register ulong a = ntoh(k[0]); 4 N6 z6 Z3 _' g+ e& d$ K
66 register ulong b = ntoh(k[1]); / M& X- ^/ @- q* I2 |
67 register ulong c = ntoh(k[2]);
1 p# S" l J Q2 A68 register ulong d = ntoh(k[3]); / p, F( a+ N# a: i; ^. V$ i" q
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ ; E( |+ B u' e& E/ w. T$ J" `* f2 D
70 register int round = _round; 6 Q9 X+ w6 |+ o* z
71 register ulong sum = 0;
6 m( G( H- U6 H7 c72
0 ~1 h, }6 J* E! ~- m% |; T; q73 if (round == 32)
4 T! @* d" |) W74 sum = 0xC6EF3720; /* delta << 5*/ / i, @7 g8 g, A7 }6 @
75 else if (round == 16) B& l% W; f- @* ^3 c J
76 sum = 0xE3779B90; /* delta << 4*/ 7 H. n5 q F, d' R% N0 M. H
77 else 1 g: E6 n$ V, V6 I% K+ H) ?
78 sum = delta << static_cast<int>(logbase(2, round));
& u) J6 _% e' X8 J8 b79 : u5 m! g9 q% X$ C8 g5 M
80 while (round--) { /* basic cycle start */ ( [- h1 v$ B: t( Y5 |
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); # N( }1 y' E4 `1 u+ i' A7 [
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
4 L6 r2 m! U& L3 @& I83 sum -= delta;
* @5 a+ t% o5 @& b c' l4 M8 _: r4 _84 } /* end cycle */
! P! S* e) g9 T' I: R0 L7 `% y85 out[0] = ntoh(y);
7 B; l! I9 U( s+ Y! M; D86 out[1] = ntoh(z);
% k! E8 j! m0 f1 S0 @) N87 }$ w4 X* i2 n; X6 m
9 ]: l' ?( \* a! u) q需要说明的是TEA的构造函数: * O; f! ]4 T4 Z6 }) D1 Q
TEA(const byte *key, int round = 32, bool isNetByte = false);
/ d; s% Y: h/ u V/ B1.key - 加密或解密用的128-bit(16byte)密钥。 5 o; ?3 t8 w6 r! M. y, n* j
2.round - 加密或解密的轮数,常用的有64,32,16。
: Y. q' r2 c- L4 Q! H9 m# u7 v3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! ( ?2 [" |- @0 h! X
\7 w7 w2 o; n8 K. j6 g) u* l最后当然少不了测试代码: |
|