|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" * k+ C& a- B0 L. |1 C
2 #include <cstring> //for memcpy,memset
: }/ D0 N$ W9 G% K4 W8 Y* ^9 f 3 ?' `* F! U1 k( T+ k5 g
4 using namespace std;
d# d4 Y+ c6 |6 z 5 ' |/ h. v" W6 n$ \; V7 B
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
/ d, w5 N0 Y9 f/ }8 C 7 :_round(round) & @1 h+ e( N9 N1 O* J' }. e
8 ,_isNetByte(isNetByte) { * F& `; R- U! k; M: {: D+ ]2 `- r
9 if (key != 0) 8 ?9 m- a; |1 M: H
10 memcpy(_key, key, 16);
* F# X+ d" L6 h11 else
* q+ [+ U8 Z' v& ?, b8 g) g {12 memset(_key, 0, 16); . Q$ e2 `$ X/ p8 t
13 }
* U6 n1 o) M0 Z" {3 Y0 b: b9 S14 6 Y* r0 l$ B7 i I) L' c
15 TEA::TEA(const TEA &rhs) ! x3 `% T& y$ L+ q, H O
16 :_round(rhs._round) 7 M' t0 v2 O2 @ {3 l
17 ,_isNetByte(rhs._isNetByte) { , H/ Z) G* u6 Y8 G9 X
18 memcpy(_key, rhs._key, 16);
$ L0 |6 D/ ?/ V( L. s9 h/ j& P19 }
, `% ^4 z$ W" v, K/ J: V# p20
+ m2 f9 r7 K' i& C9 {21 TEA& TEA::operator=(const TEA &rhs) {
6 [+ q' T8 k% q4 P4 s22 if (&rhs != this) { ( J. Z1 [, r- O/ z* K$ ?
23 _round = rhs._round;
& F( N8 h N3 n24 _isNetByte = rhs._isNetByte;
+ k1 `7 S/ h; |/ p, N. q2 {25 memcpy(_key, rhs._key, 16); " {, x$ _6 ~4 X% b
26 }
% D' V$ d+ C8 Z1 N9 J3 E! X27 return *this;
% @/ a; `* M8 Q8 T I% o1 }28 }
. V* S. ~7 R: Z: z29
9 B; S4 H/ v( Y30 void TEA::encrypt(const byte *in, byte *out) { $ `# |8 D% B+ ?: ~
31 encrypt((const ulong*)in, (ulong*)out); " y- N* x( t3 L4 |
32 } , [3 r0 T" A' C& T
33
& U. Q5 |% V, ]9 s3 M2 `34 void TEA::decrypt(const byte *in, byte *out) { " M- S. x5 @% @
35 decrypt((const ulong*)in, (ulong*)out);
! i$ g, f; O4 l$ f& R- A36 }
' N, y7 {& N5 Y37 , Z# I* ?2 g' V1 n$ ]' g- }+ }
38 void TEA::encrypt(const ulong *in, ulong *out) {
8 b- E" p1 X1 [1 I0 h39 $ Z0 e" R/ \. |; {
40 ulong *k = (ulong*)_key;
( w) O" ?6 G5 o' I- l2 R7 G' T41 register ulong y = ntoh(in[0]); 1 u3 Q/ K# E/ I9 L% C S. d; y
42 register ulong z = ntoh(in[1]);
* G0 a6 V1 s; [$ `7 |43 register ulong a = ntoh(k[0]); 8 d, l2 ]4 Q* p4 [
44 register ulong b = ntoh(k[1]); 4 v0 K' a+ M' G
45 register ulong c = ntoh(k[2]);
( X. Y6 N1 l0 r( v& N, q46 register ulong d = ntoh(k[3]); . k! T B: ?$ \7 t$ ~8 Q
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 8 H/ ^. T+ o' S" P, f
48 register int round = _round;
' {8 W* ?( g4 b3 Q7 c! W! _49 register ulong sum = 0;
6 u# W' \2 I; @0 L50
# ]3 @7 l0 O- g9 C. x/ w- i51 while (round--) { /* basic cycle start */ 2 G" H$ g; H% a. ?' o
52 sum += delta;
5 Z* F% I" `2 u! I: H53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); ( ^' C" Z4 E$ m7 D. e9 s* K8 H1 L
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
5 {! \; s- H& V; }55 } /* end cycle */
4 c/ E& M% k& ?0 c5 R* P' w- T56 out[0] = ntoh(y);
8 c+ b& f: w& K# P) R- q% O57 out[1] = ntoh(z); 9 X% I; V" [8 E7 _% \. s
58 } ! [5 C& z% s7 K- X
59
6 Q8 k; s: c: t; ^; y9 l* i60 void TEA::decrypt(const ulong *in, ulong *out) { 2 }. m% M9 T* J7 j, k
61 & { i+ M! i6 g/ d7 U
62 ulong *k = (ulong*)_key; 2 P2 Q o) I( G1 D; X
63 register ulong y = ntoh(in[0]);
- d3 C/ s V! d% ?, J9 p5 T( m64 register ulong z = ntoh(in[1]);
" H) w( p: V* }' D8 b4 l65 register ulong a = ntoh(k[0]); & C* G7 N" `' F& t
66 register ulong b = ntoh(k[1]); : }- Q# _3 ~9 I' P2 Q1 l4 f
67 register ulong c = ntoh(k[2]);
W: I& E- f% s! T' {. Y# X68 register ulong d = ntoh(k[3]); 9 E- S% Q$ c# A1 s
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
. C' [; s* @, O+ t: r70 register int round = _round;
- y, d u# X g" h8 W71 register ulong sum = 0;
* `$ ~) N- d& Q* ~% L72 * v2 d% ]9 g3 N: f/ `/ ~
73 if (round == 32)
3 z2 L; d& a: Q8 g0 A4 U# W74 sum = 0xC6EF3720; /* delta << 5*/
& d6 d- g; b" C: F6 p75 else if (round == 16) ' g* x) I. s- L0 w
76 sum = 0xE3779B90; /* delta << 4*/
1 n+ Y. N E) w8 U% `77 else + O1 ?/ G! i) m/ `3 I% o- W
78 sum = delta << static_cast<int>(logbase(2, round)); 2 u ?! U- v% D+ l6 \+ o
79 # e* Q, M: @" n8 \
80 while (round--) { /* basic cycle start */
1 b. {5 [5 d2 v81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
8 B9 F2 z: G& J, R! m$ S b82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
8 l1 T3 i2 x K* Q' {, r83 sum -= delta; & l0 x+ e0 }" r* L! U; X
84 } /* end cycle */
. E* u& U: R, y7 H. |( Y# b85 out[0] = ntoh(y);
" H' Q/ s" N9 V2 l i% @& C86 out[1] = ntoh(z);
, H7 I, M6 ?& R4 R87 }# K# g# [4 M: g& c$ S* _8 R. h
. d! z! H" ~1 s7 a
需要说明的是TEA的构造函数: * O3 m+ y$ q7 g7 O. Y, j! Z% ], n
TEA(const byte *key, int round = 32, bool isNetByte = false); % ]' K4 Y) T7 g6 K2 r2 m
1.key - 加密或解密用的128-bit(16byte)密钥。
6 z6 h) |/ I! ^$ \2.round - 加密或解密的轮数,常用的有64,32,16。 1 y9 ]3 h& G- i$ M
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
B4 D* Y' i* W# i: p! D
: e |! L0 a! z最后当然少不了测试代码: |
|