|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
/ R Z: o7 H5 ] 2 #include <cstring> //for memcpy,memset # i# r( C" }$ }; p/ q- k- B
3
5 y$ N# C" O/ \0 l* u s+ c 4 using namespace std;
$ o+ f% L: q" m/ q6 R" B4 E5 s 5 : i/ M* M7 Z& x7 z0 ~2 Q
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
2 L0 l' V& g" l5 ]' ? 7 :_round(round) 1 O2 P/ z' Y% v4 a
8 ,_isNetByte(isNetByte) { i+ K, J8 B4 v w; r: g1 q5 O
9 if (key != 0) / S' x; j5 L2 }3 k/ ~
10 memcpy(_key, key, 16);
5 m" A0 Q: z' H6 X; S: ^11 else
0 z9 a6 S' b, B4 C* T, `12 memset(_key, 0, 16); : ^; f. ?. l6 b9 w5 z: C
13 } $ e& }2 H- O6 Y
14 % [ o3 ?) G! p$ }+ g6 r: T
15 TEA::TEA(const TEA &rhs)
; ] w" j" U+ w! A8 B* c16 :_round(rhs._round) 0 B$ O8 @% A0 Z
17 ,_isNetByte(rhs._isNetByte) { : L7 O3 `, W2 G- C7 o' K& w2 \. Z
18 memcpy(_key, rhs._key, 16); " _8 D. G6 v0 C) w9 B0 j
19 } \/ E3 q7 J w' o$ d" l% w! _; {7 F" G
20 % l3 H2 M1 ]2 }3 w ^* Y) a
21 TEA& TEA::operator=(const TEA &rhs) { $ V6 B$ l6 S, u+ m( U
22 if (&rhs != this) { : L( {' ^' S' F2 M
23 _round = rhs._round;
" d1 Q5 n: @ V' s24 _isNetByte = rhs._isNetByte; - c3 H& ^! q( W" u3 l
25 memcpy(_key, rhs._key, 16);
& H/ V( E& O* p6 C26 }
/ Y% g# p% H* D27 return *this; . C4 ]' F: E9 {+ ~9 p
28 }
3 M6 p4 y6 c0 ]29
% j0 d$ J" \7 y6 h# O30 void TEA::encrypt(const byte *in, byte *out) {
! G% p8 S* ^% g31 encrypt((const ulong*)in, (ulong*)out); 0 d; {& b* g; Q
32 } 0 m: Q: l" c/ q. g- a
33
4 w; O* g) C' ]1 K. W! x' B3 j% ?34 void TEA::decrypt(const byte *in, byte *out) { - X2 G# X) M) |" U8 s" B. W+ u
35 decrypt((const ulong*)in, (ulong*)out);
; f, ], h! p$ L A36 } ! x$ d8 _! Q# m
37 / l2 [4 J$ h& a' z& v
38 void TEA::encrypt(const ulong *in, ulong *out) {
; L5 Q" D. R) T+ }2 C" z& t6 M" W6 _/ d39
/ s8 K* i9 I( w1 ]$ `% L( l0 b40 ulong *k = (ulong*)_key; : h3 p& ?7 L& R) z/ G
41 register ulong y = ntoh(in[0]); 9 N7 p. ]% G2 S0 X1 {
42 register ulong z = ntoh(in[1]); 8 x3 [" {5 a( ^
43 register ulong a = ntoh(k[0]);
4 h( ^; P; c1 f/ }' F7 e44 register ulong b = ntoh(k[1]); 0 b; \2 Z7 R t) _8 A+ C4 Q0 v
45 register ulong c = ntoh(k[2]); 6 W ~" G) Y- x0 a- B' E
46 register ulong d = ntoh(k[3]); 6 X& m& b( X) Q% i
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ % B/ d. r/ @) L: Y4 h' f. A/ d8 r
48 register int round = _round;
0 p% [; U4 g2 N; y49 register ulong sum = 0;
, h9 Z' _' i; F( N% Y1 w3 \50 . ?: n; P" }. N' V& A4 K% r) J* n
51 while (round--) { /* basic cycle start */
2 f7 y+ G; Z2 V, S% ^- ~52 sum += delta;
, _* ~/ M9 S5 ]4 |, z53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
5 i2 ?, b! x! }) H6 J54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
, U3 {( I( X% f! p55 } /* end cycle */ 0 l6 ?4 y8 x7 d1 o/ U8 _. f
56 out[0] = ntoh(y); " q; U& G( X3 I, q1 z/ d
57 out[1] = ntoh(z);
! B" E p! Y* i: R5 X58 }
8 b1 h1 l4 d1 e59 % ?3 H) o! l3 L$ g6 V* @
60 void TEA::decrypt(const ulong *in, ulong *out) {
4 v$ D" {# n6 ?/ x+ g61
/ K0 h! [7 D- ]# A6 ^% `62 ulong *k = (ulong*)_key; 9 ^$ _2 b8 C! _% X
63 register ulong y = ntoh(in[0]);
4 c: D" ?0 V7 a64 register ulong z = ntoh(in[1]);
: P9 \. m) v$ W( k: D1 e0 S+ U65 register ulong a = ntoh(k[0]); $ O0 n' @6 z3 e
66 register ulong b = ntoh(k[1]);
) X, r6 \5 B9 C M. C$ k67 register ulong c = ntoh(k[2]); - ?0 }' T% x! d7 S
68 register ulong d = ntoh(k[3]);
C' B+ X9 m. T69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ # l: W, K' w, D& V/ ]! F
70 register int round = _round; & N) { d1 o0 A5 J' p
71 register ulong sum = 0; / j0 j5 \# U$ H+ e6 M
72
" ]3 T( I7 N: X73 if (round == 32) * m. K2 Q. N: `! a+ n& l7 F5 C
74 sum = 0xC6EF3720; /* delta << 5*/
, C3 _5 W0 Q) C/ q3 ]( E75 else if (round == 16) ! P% x- c+ M y/ U4 ]
76 sum = 0xE3779B90; /* delta << 4*/
3 k; ? B, q% S77 else " v5 f8 i+ S! I* D% I
78 sum = delta << static_cast<int>(logbase(2, round));
( Q6 H2 S1 U9 t- e& k2 ]79
) o( X/ B: G0 d8 d$ i9 d) ^80 while (round--) { /* basic cycle start */
; q3 z. V) K' \7 g! {( b81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
+ l6 ~# s) x2 N1 b! P% x/ @& @6 g82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
/ n$ Y" n* G& j' N/ L( m. V83 sum -= delta; % K' G7 _! J, n6 Q
84 } /* end cycle */
" y2 p/ L" {, |, v( Q# b F. E4 a85 out[0] = ntoh(y); , r B2 o d. w3 Y3 E; x D/ H, c" s
86 out[1] = ntoh(z); 7 o! O2 O4 @' E, K# \1 Q3 M1 S# B
87 }: H, H1 R: f/ `& b; w+ C; h
( A6 u0 x7 B* _8 W
需要说明的是TEA的构造函数: 5 k T( h2 j0 q$ n; I6 [2 \/ w, w
TEA(const byte *key, int round = 32, bool isNetByte = false);
/ H$ J4 y8 y) e m7 A- q# |1.key - 加密或解密用的128-bit(16byte)密钥。 ( g7 {8 J% D5 h
2.round - 加密或解密的轮数,常用的有64,32,16。
' k+ [* O$ w6 _2 U* n/ P& G1 ^3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! 3 s) X% w( H* N W; V9 i
5 D. d6 ~# j* U9 K* ^, `最后当然少不了测试代码: |
|