|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
% P0 H/ J" y% @1 ] 2 #include <cstring> //for memcpy,memset * J+ b, Z4 v H7 ?
3 , w/ b. v2 W- u- Q5 r6 _/ \) q
4 using namespace std; 9 n1 F. c6 x/ {/ `
5 3 l, z3 J! u ]5 \
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
% \3 Z8 U3 G/ \! j4 L% W6 }7 c* F 7 :_round(round) # c# v/ a1 A) o6 j
8 ,_isNetByte(isNetByte) { 6 _" {* e3 X! K
9 if (key != 0) - ]0 \# w/ P) ]9 \2 x
10 memcpy(_key, key, 16); ! G3 _! U* l1 M5 L6 M: U0 z
11 else
, G( Y# z1 C" H% N6 ~% F! C12 memset(_key, 0, 16); 4 |. J1 h+ c- {! r8 M+ O
13 }
9 o9 C* V4 T: N14
2 z: n% e& Q+ l15 TEA::TEA(const TEA &rhs)
" k1 X3 u- W0 Z8 l, g9 B7 S16 :_round(rhs._round)
/ F+ @4 Z# X, {3 t) a5 a; D2 F; ?9 u17 ,_isNetByte(rhs._isNetByte) {
- y$ S, g5 T" K18 memcpy(_key, rhs._key, 16); 9 z* ?6 E3 Z- I W7 n
19 }
3 y( V" I6 m' ^! y7 |20 4 i- M+ V3 X9 J0 }1 ]4 A
21 TEA& TEA::operator=(const TEA &rhs) { 5 A/ [* y& F* {) G# j8 j2 Z7 m9 \! S
22 if (&rhs != this) { ; [. }# N/ E: ^7 j, d
23 _round = rhs._round;
: S3 n1 f5 z! C( }; }+ j24 _isNetByte = rhs._isNetByte;
3 y D6 H& d' c; T4 M/ A) R25 memcpy(_key, rhs._key, 16);
! z& n0 c, n4 R s. U. G26 }
3 ~; r; \+ F) g" ~( k# v. k27 return *this; # T. h4 `% z5 Z2 D8 o
28 } # c; f. f$ C3 S3 E0 ^# H: d
29 : [. T! g" c: Y, a
30 void TEA::encrypt(const byte *in, byte *out) { ( Q7 ?& O, W* \5 o0 [. {' H
31 encrypt((const ulong*)in, (ulong*)out); ) g* c: s8 |/ L- q! E, x7 K
32 }
* z$ U( r7 G6 F6 M! O2 s5 |3 `33
6 @; Z* @- @; A34 void TEA::decrypt(const byte *in, byte *out) {
: N. k. I# d# d4 N6 { \/ s35 decrypt((const ulong*)in, (ulong*)out); , Z4 l! _3 i) j3 `
36 }
3 y) F1 t0 [' ~1 I: I# E2 _37 , M* Z% N; b# d0 B
38 void TEA::encrypt(const ulong *in, ulong *out) {
' o, T" h5 f* {/ ~9 x7 N* Q39 7 p1 [! T, s, r$ G% Z5 T0 }7 q
40 ulong *k = (ulong*)_key; ! v. J) r5 w. t6 H& n( D! w# ` ]
41 register ulong y = ntoh(in[0]);
2 Y% p0 W" y" n$ C) ]5 M0 A0 m& P42 register ulong z = ntoh(in[1]);
# m: H! K" f/ h3 r+ r43 register ulong a = ntoh(k[0]);
; w, i* u3 M0 j% n0 M0 k: `44 register ulong b = ntoh(k[1]);
. t3 L$ E4 H* y7 q1 v# L45 register ulong c = ntoh(k[2]); ' a8 `" G# L7 P2 P$ }, L. r
46 register ulong d = ntoh(k[3]); , d4 e5 f0 P8 O; t" I2 D0 M
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
+ Z1 v R# B- d: f7 d2 ], ~48 register int round = _round; 8 Q/ z: F( O6 \' [9 A- @
49 register ulong sum = 0; : g2 G& H5 |+ s, j+ _0 h5 Y
50 & L0 Q, {) Z! i0 h
51 while (round--) { /* basic cycle start */ 6 E. w) _5 E; q W# o) G9 c( J
52 sum += delta;
, n3 c) g! v2 u+ H+ G! ], [53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); " A0 W3 @. H7 p! H6 z+ r" Q
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
0 _# s- o8 ]3 M/ G55 } /* end cycle */
0 q. w m1 ^4 m+ D. N56 out[0] = ntoh(y);
+ b+ A! J3 F4 D' v; ]57 out[1] = ntoh(z); ! _! u; L( }: h9 [( H1 A6 x
58 } , Y6 T# y8 I% s$ M
59
4 t" u) v, i# P0 ~$ |, N60 void TEA::decrypt(const ulong *in, ulong *out) { . c4 N7 T' a3 f
61
! D% [2 b V; E8 }! _7 ~62 ulong *k = (ulong*)_key;
; }4 x- y- O* U4 @( \63 register ulong y = ntoh(in[0]); ' u) X$ m' z0 F! r' c/ ~4 y
64 register ulong z = ntoh(in[1]); : A6 Q) f3 L; z$ B4 h ~ I9 i4 q
65 register ulong a = ntoh(k[0]); 5 p4 G; t& L( ~2 U8 k" p5 a
66 register ulong b = ntoh(k[1]);
/ y6 M0 v/ G& s7 {1 R7 w0 s# ~$ G67 register ulong c = ntoh(k[2]); ( @" J9 Z4 q, ^$ _4 S2 }9 s
68 register ulong d = ntoh(k[3]); + G" q$ h. o* R; n/ X
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
+ h$ t, F( m B1 T$ [4 z70 register int round = _round; # f! Z. P2 p( ?
71 register ulong sum = 0; , k( Y B6 `8 y0 H' s1 f
72 & M% A, z! ?$ p6 j# k
73 if (round == 32) : E8 H# S/ \. a( ^+ C
74 sum = 0xC6EF3720; /* delta << 5*/
# f- i5 H% k9 } M4 {* \* V75 else if (round == 16)
i) K- Z% ?3 ]3 n! M7 n$ V76 sum = 0xE3779B90; /* delta << 4*/ 1 o4 j2 _1 \$ E- c0 n) Y# V$ p$ k6 j
77 else ! A" F9 F' v; i1 c
78 sum = delta << static_cast<int>(logbase(2, round));
- [3 {9 L2 r% N2 g6 k79 , A i# }+ ?: r+ [ v2 F
80 while (round--) { /* basic cycle start */
6 Z$ @) ]7 _* `) A+ D( H81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); % E1 v6 K) X0 W! g: N5 W
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
/ @' }1 u' k1 u83 sum -= delta;
0 q* ?- l4 Q4 ^7 k* y! U, A) X$ d0 y84 } /* end cycle */
1 {8 [2 X0 D$ _5 p2 v* c85 out[0] = ntoh(y);
7 S( V+ B }/ u, ^# @" S8 ~# R86 out[1] = ntoh(z); 2 }9 O8 G2 {* h! J! O5 \2 a' r
87 }9 Z. {- A6 j {, B; r* M. q
$ s1 E4 Q. m3 Z7 V% w+ V% g4 U8 U( \9 V需要说明的是TEA的构造函数: + i1 Z: M# J% u; i6 Q8 j7 @
TEA(const byte *key, int round = 32, bool isNetByte = false);
7 y9 \$ Q. w# \' s) }( l1.key - 加密或解密用的128-bit(16byte)密钥。 - {1 e' L5 F! {/ n: c
2.round - 加密或解密的轮数,常用的有64,32,16。 ! X) `6 `3 j8 N- I6 u* k$ P' p
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! . q2 k* @2 ]& H: j
0 S/ b E9 X9 \0 N最后当然少不了测试代码: |
|