|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
; M2 ]# \9 O0 ~# d( |* a 2 #include <cstring> //for memcpy,memset ( M0 h# I+ \) k, E& V
3 6 s# z( n5 v/ j4 X4 }2 ~
4 using namespace std; . f" q# b) |; O/ k% E. [' h1 s
5
: d3 E: u" x) C6 g* B, O 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
) F/ A* ~( Z3 t# u 7 :_round(round) * n9 E( E8 j; P; E1 u: F
8 ,_isNetByte(isNetByte) { ! ]+ U/ ~* A! ]" k% B9 }
9 if (key != 0)
% h) Z! T5 W0 j6 e7 C. [10 memcpy(_key, key, 16);
- i/ |8 T: j0 G3 ]! A% l11 else
/ ]+ K$ Q& ]6 y5 q12 memset(_key, 0, 16); ' A% k6 H. `8 i% O
13 } ! `9 e) Q& U0 q: _4 ^: V- ~
14 , s" |9 f% q+ H5 ^" S
15 TEA::TEA(const TEA &rhs) ; I$ M8 n4 s' R5 V/ h# c9 x
16 :_round(rhs._round)
( ?% B$ h& q/ B7 I17 ,_isNetByte(rhs._isNetByte) { 3 b! O4 N& e7 P4 _0 P. T; }% q
18 memcpy(_key, rhs._key, 16); 8 @+ L" A: t4 D5 O) A; N0 ?6 D7 U: S
19 } 5 H' S$ b" ?$ ]" J2 M! }) w
20 : \7 T3 @% ?+ @! o; X- K& M
21 TEA& TEA::operator=(const TEA &rhs) {
: X3 k2 x; k4 ^( i' P; K22 if (&rhs != this) {
) V. x" L7 l9 E- u6 l; s23 _round = rhs._round;
- }$ q' v1 c1 r8 R24 _isNetByte = rhs._isNetByte;
- U3 z5 C- g* W+ d3 i( Q& d8 W25 memcpy(_key, rhs._key, 16); , K6 m& y1 {1 h
26 } 1 b; O$ f$ P* z7 ^5 k7 W
27 return *this;
2 z2 u- G3 `. P1 ~& }7 x28 }
y% X& o: ~/ d* ]29
( W a# b8 [ c0 {' K d1 _30 void TEA::encrypt(const byte *in, byte *out) { . z: _% \! h o
31 encrypt((const ulong*)in, (ulong*)out); 9 O) \+ ^8 @1 A- X: l! O
32 } : D3 B, {* @7 b/ {' j
33 & r1 s0 w _/ I+ H
34 void TEA::decrypt(const byte *in, byte *out) {
2 b R- G0 k) q: [4 M4 S35 decrypt((const ulong*)in, (ulong*)out); ; S0 h! k4 }" n$ ?% x. u
36 }
( j+ ?% A* t. T' g/ E% ~6 \4 q37 3 @/ o2 ?$ k, N& X
38 void TEA::encrypt(const ulong *in, ulong *out) {
3 d5 `# X9 @, K/ ^- D39 0 q' a8 C) q% d$ \1 C
40 ulong *k = (ulong*)_key; / @1 j6 v) _* K% `8 }
41 register ulong y = ntoh(in[0]); ! S: Z7 j; I5 G/ ?; e: G3 @
42 register ulong z = ntoh(in[1]);
# k: P3 j& B* `0 b43 register ulong a = ntoh(k[0]); 2 @* l# k, p8 U, z2 t4 ^3 S5 f% K% h2 c
44 register ulong b = ntoh(k[1]); 6 F. u; t0 T4 L6 {( `+ a; v, u5 n' m
45 register ulong c = ntoh(k[2]);
# R- @( o' N- s4 U. v- S46 register ulong d = ntoh(k[3]); * j1 K! `. Q1 A! C s+ d
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
" G: j/ U" |9 B4 `$ j8 n48 register int round = _round; ; o1 ~3 x5 c- O
49 register ulong sum = 0; * b& L4 D4 @, y; g1 A0 L
50 8 R) a. \. h9 n+ F
51 while (round--) { /* basic cycle start */ ) G0 A& z& D/ J6 r4 E2 p" B
52 sum += delta;
% T6 L& `& N2 o! O" U53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
5 I: R- c4 a; E' k54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); . ]. R3 E+ n- y: q2 L
55 } /* end cycle */
) Q" q7 F6 L6 x, i$ Y% a3 D56 out[0] = ntoh(y);
$ G1 H7 t; q( [# Y57 out[1] = ntoh(z); 1 d* _, g: Q& P& W
58 } 9 y) B8 S( O' N/ j) N
59
% T6 p! X; I1 f) k- I60 void TEA::decrypt(const ulong *in, ulong *out) { % P4 h: a7 Q, R" y4 o5 d" v2 E" s5 |4 M
61 3 h1 z6 Y2 ^4 i% X2 J
62 ulong *k = (ulong*)_key;
, w& Q3 ]0 G: l* [8 S4 J63 register ulong y = ntoh(in[0]); ( S. r! x4 d0 a; C q1 i- g' H
64 register ulong z = ntoh(in[1]); 5 b C# P# n3 \
65 register ulong a = ntoh(k[0]); & j! k) a$ b4 e
66 register ulong b = ntoh(k[1]);
) w& @5 Z' \% d1 n% W0 B67 register ulong c = ntoh(k[2]);
& g( {6 `6 s/ G! E68 register ulong d = ntoh(k[3]);
0 _8 Q# P6 L' a4 c, k2 y69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 9 x$ {/ T2 d' X. r2 q, ^; i/ I
70 register int round = _round;
2 p# G5 j/ e! |% \) m7 {71 register ulong sum = 0; ) i# w: n2 v: l0 T: r/ i" g
72
& B( N$ a8 M$ V$ w) H73 if (round == 32) $ V4 d; E- P9 F0 q) H
74 sum = 0xC6EF3720; /* delta << 5*/ + P) ?& A3 Q. n4 k: Y
75 else if (round == 16)
7 U7 L2 w( B# K2 @" G76 sum = 0xE3779B90; /* delta << 4*/
# X& F8 L# A: C77 else
- g9 V, E+ }" {- X5 @0 a ?78 sum = delta << static_cast<int>(logbase(2, round));
* _: r+ S3 {/ X% C79 2 P; [ A& t. o/ ?6 i. G5 x
80 while (round--) { /* basic cycle start */
. G8 F4 n- ~9 Y* ^! d9 l81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); ! s) O, D$ G1 Y
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
* M8 B3 s- }$ ?) ?4 f83 sum -= delta;
% d1 d+ w) X3 L F3 n0 E2 k" I84 } /* end cycle */
3 `1 S4 u1 z5 Q9 K; N85 out[0] = ntoh(y);
& b6 j* R( ~5 k86 out[1] = ntoh(z); 8 p9 m6 E1 ~! Z" P- Y. {% v
87 }$ s% y* u* c0 y* @' R
) f2 l0 F5 j% J
需要说明的是TEA的构造函数:
. r7 t H+ e: w6 H% _# E# [TEA(const byte *key, int round = 32, bool isNetByte = false); 7 G: t# w! [: X2 Z8 o
1.key - 加密或解密用的128-bit(16byte)密钥。
7 q9 ?+ E M+ S9 T" e3 M2.round - 加密或解密的轮数,常用的有64,32,16。 + i/ T' X5 @/ N) F/ w$ C! v
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! . \1 i v1 g s
( _, p( {; \8 ]" A, d最后当然少不了测试代码: |
|