|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
5 e t" V9 ]# C+ _6 t3 C t 2 #include <cstring> //for memcpy,memset
; j0 _2 }( J8 u4 D 3
y W8 B: B; a" d5 C 4 using namespace std;
6 O0 d$ C8 Z" C6 g: o 5 7 B' E3 E# T6 H& t" }0 t" m! |
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) % B* ~' i, t' w
7 :_round(round)
D. d: d! C+ a. Z 8 ,_isNetByte(isNetByte) {
$ `( @+ i: S. j1 S3 H! } _; l 9 if (key != 0)
1 U# u& X2 }. q P4 r/ I10 memcpy(_key, key, 16); ) j7 f8 c" ^3 g
11 else
. a! w& g- F0 k! x# P% I12 memset(_key, 0, 16);
1 {- n; u0 l5 _ U, T t9 h13 } 7 K$ X4 q: ?6 r# g0 G) Q9 O% c
14 4 f; |* ] q( }% ?2 L
15 TEA::TEA(const TEA &rhs) ( _* x/ e1 j( R% b% i/ \( S) V
16 :_round(rhs._round) # N, |' u2 a. w! E
17 ,_isNetByte(rhs._isNetByte) { 6 c4 M% q6 @2 l1 O- m" F3 N* {4 e
18 memcpy(_key, rhs._key, 16);
* \: ~2 o2 \. x5 W# m) N19 }
3 \# S* y6 `. ~; L; @20 ' h l6 U/ ~4 s% U: w4 Z3 T
21 TEA& TEA::operator=(const TEA &rhs) { 0 |& ]/ x( A1 W7 E, l
22 if (&rhs != this) {
- b" `9 M+ P, D23 _round = rhs._round;
- w8 _/ \/ U: l/ z24 _isNetByte = rhs._isNetByte;
! ]1 A" l$ n2 r0 {: z% q25 memcpy(_key, rhs._key, 16);
0 d0 {2 k9 v$ i+ S+ b. h7 [, l6 T1 K9 e26 }
, S1 A' k3 J8 O& W8 ~; @27 return *this;
5 ~6 {" T# Z$ B0 |3 [9 [ E28 }
7 n I: S7 _ s0 c6 n29
3 `% b' o) D8 l |30 void TEA::encrypt(const byte *in, byte *out) {
$ T4 ?1 {/ u+ N31 encrypt((const ulong*)in, (ulong*)out); . z6 s2 X( w/ W& C, k" d- @9 ]8 c
32 } * m, g; b, y1 v6 s) l9 B f
33 % w) Y+ @5 g* T
34 void TEA::decrypt(const byte *in, byte *out) {
+ i7 Z! X4 D8 k35 decrypt((const ulong*)in, (ulong*)out); 0 Y; U& |5 x* E9 ^) Z# ], r, l2 v
36 }
9 ?" M, p, Q. } l0 g# [/ S37
( \; x4 g8 H' q' O8 U7 x' N4 x38 void TEA::encrypt(const ulong *in, ulong *out) { $ }6 G& R! z& y' ]% j
39 ) @3 x5 E% M$ u" K6 s
40 ulong *k = (ulong*)_key;
9 X* v! n7 l3 s+ y# s41 register ulong y = ntoh(in[0]); 5 i4 g0 B$ f# B# Y
42 register ulong z = ntoh(in[1]); . H% f% M; A \8 V7 q* l
43 register ulong a = ntoh(k[0]);
3 q8 X1 i. o+ k' _% t44 register ulong b = ntoh(k[1]);
& f7 {" M7 X8 {1 U45 register ulong c = ntoh(k[2]);
: I+ | N7 D* h$ c3 o; g" Q8 y) s46 register ulong d = ntoh(k[3]);
2 ~: \4 B% T8 J/ X4 [47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ . I/ \5 J2 n5 u d) [ j
48 register int round = _round;
. O! P) v$ f% m$ M( b49 register ulong sum = 0; 4 w3 y% `1 k3 S5 s8 c2 q
50
]* C0 i$ j6 {0 v- | U51 while (round--) { /* basic cycle start */ * l3 K9 Q! }# B7 r
52 sum += delta; 4 ?% m; @4 |3 w' H5 z
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); ' ~1 A* B l( G+ |5 S# Z/ q; M
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); 0 Y5 Y) F: a/ ]) k) E1 z* c# r" ? m
55 } /* end cycle */ ) r# l+ ]+ |) `0 X# |
56 out[0] = ntoh(y); & K, t: u: Q2 [4 N: H& u) y
57 out[1] = ntoh(z); 9 k) e/ b2 _/ W* X; f& Y
58 }
6 P3 v: _) y) p# ]: T' e. ]% }" T3 t59
3 w9 T+ F5 T0 p( r$ m" J60 void TEA::decrypt(const ulong *in, ulong *out) { 1 ~ f; |+ f% z. I0 ^" M
61 : _/ B4 i' U) [3 h0 [3 Y
62 ulong *k = (ulong*)_key;
% o: l- q6 L3 \# a! Q+ n7 E/ v. R63 register ulong y = ntoh(in[0]);
H2 \ f9 Y+ ?. _- [8 o) i1 w64 register ulong z = ntoh(in[1]);
# A* r G- y/ P6 C: _! E- N65 register ulong a = ntoh(k[0]); 9 e, _) [- o! z, Q- H" l8 M( @! j
66 register ulong b = ntoh(k[1]); ) E# W [8 v# C- \& k8 c y4 B: w
67 register ulong c = ntoh(k[2]);
, A; i$ i( u+ b! {% h# P* l' v. o68 register ulong d = ntoh(k[3]);
& J7 k7 q. R& W' F) p69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
* _, n( d- G: U7 |70 register int round = _round; + i6 d: t5 e _6 b2 o3 B/ b% |. Y
71 register ulong sum = 0;
1 W1 u2 \1 t. `. X72 9 z M2 B1 k9 g2 L; t
73 if (round == 32)
- a, l6 R$ h5 R1 z" W4 P: A74 sum = 0xC6EF3720; /* delta << 5*/
8 O i, ?7 ^& {0 W, D) X$ z75 else if (round == 16) 1 O* X2 W8 \3 `% v
76 sum = 0xE3779B90; /* delta << 4*/
9 T" _& t9 H6 x+ _) B# C- }2 k77 else & { k6 y2 R9 H6 O3 w
78 sum = delta << static_cast<int>(logbase(2, round));
6 i3 G; z1 X: @+ g79 ) ]0 [+ ^( W: k+ C5 K& q
80 while (round--) { /* basic cycle start */ 7 {7 S8 K5 w! E7 V$ S
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
1 p0 m1 `8 o) }82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); 3 b( Q3 u* M- g- i: C& `
83 sum -= delta; 2 Y7 P; {1 p4 C! `
84 } /* end cycle */ ; \: C5 B, T6 x* D9 M( }/ S
85 out[0] = ntoh(y); / ~" C0 R K! x9 s/ e, v
86 out[1] = ntoh(z); 7 J, L2 K" N9 B, G, Y8 @: N
87 }
- I3 {1 u, J; I+ n, g( I9 t
% L1 V) q4 M Y0 N, F需要说明的是TEA的构造函数: . v5 g* f9 {6 L9 r- @' ^
TEA(const byte *key, int round = 32, bool isNetByte = false); ! Z: J7 O) X2 i/ t
1.key - 加密或解密用的128-bit(16byte)密钥。
' g, O3 ^( @- {$ e2.round - 加密或解密的轮数,常用的有64,32,16。
' P; N/ P4 {9 |( I/ D3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
* k5 q, U. N2 p$ }. |8 }$ a k& ?; R# L) x! V; D
最后当然少不了测试代码: |
|