|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
3 q4 N, p& D5 a/ u 2 #include <cstring> //for memcpy,memset
5 O! Q( B' o. q$ ]& O) ~0 e 3
e* S: ^) b, c. L3 B" D 4 using namespace std;
0 p, n) h# g( L' [ 5
3 R, V, j3 Q- G( _ 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
9 l! h" N+ Z1 g. |# z( n 7 :_round(round) - D# C- e) b' z0 j' W
8 ,_isNetByte(isNetByte) {
& P: s5 D8 B+ E- U ^ 9 if (key != 0)
+ c/ h, W, h7 o D- c10 memcpy(_key, key, 16);
+ q# P7 T- T6 Y5 j2 T; x: U8 C11 else * b. B9 Z; M$ J/ z9 r4 l
12 memset(_key, 0, 16); 0 f/ w! d, f4 }8 C6 F; s+ \/ v
13 } & b8 @" [* [: ~' U' N1 O
14 . h1 U$ u9 V( S: @
15 TEA::TEA(const TEA &rhs)
7 c3 ~5 u: `4 ]8 L; K" T V16 :_round(rhs._round) 2 u7 x9 w/ j: k$ Z* k( _- D
17 ,_isNetByte(rhs._isNetByte) {
$ m- }) c* e0 y# P0 c18 memcpy(_key, rhs._key, 16);
" Y. U F. N) Y3 b$ Q8 J1 z3 G19 } 8 e$ ~4 b8 n7 t: i7 {7 T1 h; Y
20
- L1 r0 y- b7 F/ @- j- c. Y21 TEA& TEA::operator=(const TEA &rhs) {
0 f$ i" [3 @8 m" c22 if (&rhs != this) {
& e& g2 `: W' p/ \; x# G" R23 _round = rhs._round; * x; T" p" M* v9 q0 Z
24 _isNetByte = rhs._isNetByte;
% B; c, j4 h6 D1 B5 p8 |25 memcpy(_key, rhs._key, 16);
7 t f% T. ^& N7 ]: B8 g! h( y26 } + H9 l8 w) Q1 C' y# Z, R. h
27 return *this; - h% j9 ]; P0 C& k& m
28 } 2 Q4 N/ ?- p7 }1 f# l4 r8 l4 R
29
+ U$ f- C5 Z0 ~- P8 n" H. s% m30 void TEA::encrypt(const byte *in, byte *out) { , t, m% T. G: D6 R1 _% }
31 encrypt((const ulong*)in, (ulong*)out);
* V8 I# v& Y% }# W32 }
0 h# I( Y C; `$ F33 & J% p7 U* l G) i! L5 M
34 void TEA::decrypt(const byte *in, byte *out) { * G& G+ y2 }: P+ Z/ `( F
35 decrypt((const ulong*)in, (ulong*)out); 7 p" {' L, o4 X, ^/ E G
36 } * a$ n# Z! I5 p" T; H! n# \3 B& c
37
6 L2 b2 C' B. C38 void TEA::encrypt(const ulong *in, ulong *out) {
& S. [7 {* ~# q& y. X+ n! {4 r39 % y9 N. C# [1 Y2 p
40 ulong *k = (ulong*)_key;
( k$ ~. X; a, N y& }41 register ulong y = ntoh(in[0]);
" Z1 h/ O- c W3 B42 register ulong z = ntoh(in[1]);
" v" J* u5 y- J7 p8 c A43 register ulong a = ntoh(k[0]); / g% ~! k% ?7 |4 J
44 register ulong b = ntoh(k[1]);
8 h3 F7 J, N0 h4 M" m45 register ulong c = ntoh(k[2]); , x* B. G! I6 [$ z
46 register ulong d = ntoh(k[3]);
' Q) o5 k# u2 H1 F47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
* k3 {% l/ D+ `' q; P/ y48 register int round = _round; ! w! T& |4 l' q2 J0 U B
49 register ulong sum = 0; % @0 `8 O0 |+ I1 W( q2 V
50
. {; R: F4 k9 Q! i( o9 b- y7 U51 while (round--) { /* basic cycle start */
2 D6 G) d( ?3 _1 V9 a52 sum += delta; 0 X1 a2 D( d2 u
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); 6 W O! h; p5 E$ I2 ~+ S! y7 U
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); 5 B- B+ K, K! f& _
55 } /* end cycle */ 6 i. J& U8 g* Y, [3 f
56 out[0] = ntoh(y);
. }/ a, J0 v; y- g4 z+ w57 out[1] = ntoh(z);
. W2 U# \) E( X& h58 }
( x% G" L. }2 d/ x9 {59
' K5 ^+ o5 F! P) Y: R. L60 void TEA::decrypt(const ulong *in, ulong *out) { * K' R' E/ n7 k1 q* f
61 : b& A% t4 v |5 H/ t
62 ulong *k = (ulong*)_key; 6 X1 e! B% m; |- e) T, Z
63 register ulong y = ntoh(in[0]); & i3 M; `/ }8 T' c+ v o
64 register ulong z = ntoh(in[1]); . l# B7 ]9 e2 \
65 register ulong a = ntoh(k[0]); 1 D: X" n' N2 C! g
66 register ulong b = ntoh(k[1]); , S _0 O/ h. |* k, _0 X& _+ B0 z' N2 o
67 register ulong c = ntoh(k[2]); 5 P0 X4 `3 X5 l
68 register ulong d = ntoh(k[3]);
& _+ A3 T, K, @ A69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
# s+ ]+ Q+ [; r- |" B' T' R70 register int round = _round;
2 G# @% p u9 @, t# E" T71 register ulong sum = 0;
* k7 E7 d( ~( I# R) H+ o5 t72 : W. W) p) y8 U2 ^* v
73 if (round == 32)
- V3 K( @2 f, A) }6 G" g74 sum = 0xC6EF3720; /* delta << 5*/
" J& t$ b% _$ K4 K8 Y, [75 else if (round == 16) ' m0 x" _/ y/ p" {, s1 G
76 sum = 0xE3779B90; /* delta << 4*/ 9 q& P( v) j& ~6 j5 G% t
77 else 3 B% X9 U/ B8 f! V) g0 o
78 sum = delta << static_cast<int>(logbase(2, round)); 0 m7 v! I( M8 ~/ j6 \9 U
79 % v. g* q2 A4 M4 `) e2 @
80 while (round--) { /* basic cycle start */ . I5 I( |" @; A M( O9 U6 y$ Z
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
, k2 r W, |' U5 c+ p7 k82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); 6 _$ Q# q9 `) F% o. T
83 sum -= delta; 2 h8 n' v. \/ e$ _9 v( y A
84 } /* end cycle */
- t: ]+ F- r* U: f% X' j85 out[0] = ntoh(y);
8 I; h8 b1 N) {! h) X86 out[1] = ntoh(z);
% t* \( r! u% j; g' L& O3 t87 }
: s3 T; b' j, I$ q7 F2 W0 O# O- X: [0 S6 H1 k* h& L2 k3 ~
需要说明的是TEA的构造函数: # [* M q+ _7 Q' v; ?2 _
TEA(const byte *key, int round = 32, bool isNetByte = false); ) I2 t9 ]) y4 Z2 \1 q' g
1.key - 加密或解密用的128-bit(16byte)密钥。
$ S( G8 m4 l4 L) C2.round - 加密或解密的轮数,常用的有64,32,16。
9 ]9 G/ I3 O( Z& v3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! * o7 i0 J; R# n9 {
. z2 n- g5 y: U/ X$ l, f2 M0 Q
最后当然少不了测试代码: |
|