|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
/ c7 I; M& B, M7 f 2 #include <cstring> //for memcpy,memset
8 n8 e, A* B# O3 Z) |1 P+ \7 @: @ 3
; h9 Z5 R8 v, f* ~& n$ k4 B 4 using namespace std; ' b; k/ J& |. M$ c7 R% d
5
( z2 a: ^8 C% v0 T" A7 {. x 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
- R+ D1 C0 Z$ t; G5 ?0 R% F 7 :_round(round) 5 {) _/ x% P s9 `; M7 F
8 ,_isNetByte(isNetByte) { 6 j, \. S+ S. s5 y
9 if (key != 0) 8 M( Q! d% h/ L- n! @( q! I6 W# v
10 memcpy(_key, key, 16);
3 D$ a( F" m) G- r11 else
8 s M" E, ^2 J12 memset(_key, 0, 16); 2 p0 H6 \+ K! ~6 N/ T/ S
13 } 6 r' u9 S. i' M+ @* @
14
/ j+ K' P. C2 U8 g8 H6 ^/ V15 TEA::TEA(const TEA &rhs)
1 l6 f- N3 s* Y8 i16 :_round(rhs._round)
2 U8 F; P9 y$ V: I6 S) Z17 ,_isNetByte(rhs._isNetByte) { . O% E# F) H8 U" D( {6 V4 p
18 memcpy(_key, rhs._key, 16);
`1 `3 v: c* @6 S8 I19 }
: h, E" \5 d' y20
1 Q9 V0 _: E0 D( Z' |21 TEA& TEA::operator=(const TEA &rhs) {
5 s- n! r0 h* \- i3 B1 a* Y22 if (&rhs != this) {
) a9 u0 v" }+ K' ~- s23 _round = rhs._round; $ S) P$ s- |( [" z5 e
24 _isNetByte = rhs._isNetByte; ' L" S% o& |5 G
25 memcpy(_key, rhs._key, 16); * l. E* p0 I9 o$ b3 e/ h! G
26 }
( x# U. e9 A) F27 return *this;
: ~. M! A4 B2 r+ u0 N! e5 a28 } * I- c6 @( w( [0 g2 v# P
29
- ~& l! K5 v+ \30 void TEA::encrypt(const byte *in, byte *out) {
- Y8 |+ A- L7 |3 s' p/ c31 encrypt((const ulong*)in, (ulong*)out); $ P( L, K+ z$ t8 ]$ M
32 }
& C7 r5 O& V2 {- R' I33
3 V9 Y3 C2 I6 h7 L! u34 void TEA::decrypt(const byte *in, byte *out) { 6 Y- Z5 B5 x9 |+ }& m1 J
35 decrypt((const ulong*)in, (ulong*)out);
, v- u# \' l+ H* `9 k; P5 u36 } ' R8 T5 E% z3 A( S8 N0 ~! L
37
8 W9 ~# ?7 Z/ o38 void TEA::encrypt(const ulong *in, ulong *out) {
- k7 {* i7 m2 K$ V1 c+ X39 2 l5 D5 [ A" W# C) j1 j
40 ulong *k = (ulong*)_key; 2 F; @1 M# T% G0 I3 a. W
41 register ulong y = ntoh(in[0]);
, [6 ^" Y: l, R, D, q) H42 register ulong z = ntoh(in[1]); - A8 w+ j1 T2 i4 Q& [
43 register ulong a = ntoh(k[0]); m4 ~, }7 v4 K
44 register ulong b = ntoh(k[1]); 1 U0 v) ]: H/ }7 O( u9 m
45 register ulong c = ntoh(k[2]); - N+ R' Z# d2 w# ?$ b" Y, Y
46 register ulong d = ntoh(k[3]);
" q. j8 t! z/ h) h& Q47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
" ]4 H+ g: s9 I. V/ x48 register int round = _round; - G' M8 N+ [& a* e: k3 ~" [! ], X
49 register ulong sum = 0;
4 W) U$ o# G4 Q; B0 l; i50 - m4 ]9 p! J. x& H
51 while (round--) { /* basic cycle start */ ( O2 [9 }9 g" W9 f6 S. E* W
52 sum += delta; ( o$ \+ o; x' b+ g: J w# \. J
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
z5 }% ^6 n- [/ b) w- \54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); 5 q- F' i2 C# u, M( ]6 Z
55 } /* end cycle */
+ X* o% A2 O: o) P56 out[0] = ntoh(y); 1 o* W. W$ I7 ~' _, x6 O
57 out[1] = ntoh(z);
7 \2 h& ^8 }2 L1 Q; n+ V+ q" f58 }
' G j9 y* r }) X: r( x0 @/ w# R59 . F5 e+ f; c6 m# {8 {. v$ s
60 void TEA::decrypt(const ulong *in, ulong *out) {
1 [ G. e- U/ F4 ]61
; o% B, r1 o* w: r2 r& g62 ulong *k = (ulong*)_key; : z! X3 z9 H3 R b! \- G
63 register ulong y = ntoh(in[0]); 5 h& ^- k% }; i! `; E. m9 \
64 register ulong z = ntoh(in[1]); + Z6 M) x0 W& G6 g: ] q' P% u& L
65 register ulong a = ntoh(k[0]);
3 K# g R5 v# R" ^: I1 l66 register ulong b = ntoh(k[1]); 8 M" U- k2 y) p" {" h
67 register ulong c = ntoh(k[2]);
' \, L! y: s( F/ q4 o68 register ulong d = ntoh(k[3]);
: m' p6 T4 S X8 Y$ H+ L& j, B69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ & B- {4 }- |- a4 a4 \6 t z) c
70 register int round = _round; * u$ {8 r* Z9 w4 k
71 register ulong sum = 0;
9 Z# u! ^! }0 o2 o4 n72 ) y1 n4 v7 q) G2 \, [0 H
73 if (round == 32)
0 Q; a2 W6 L1 t- J3 Q* f: O74 sum = 0xC6EF3720; /* delta << 5*/
2 m% H- i, c' \& e7 n9 x8 c5 e75 else if (round == 16) ) W9 U) C! ^, i$ I! e
76 sum = 0xE3779B90; /* delta << 4*/
" o* P5 a( H! k5 S+ w- @$ ?2 T77 else
" M9 Z7 r' d: S* m2 S" p78 sum = delta << static_cast<int>(logbase(2, round)); 2 _2 [( W4 u+ {+ h" t
79 9 J. a" a! z( e* \" ^& {" }
80 while (round--) { /* basic cycle start */ * t. d3 f6 t( o0 ^5 ^) R, s$ t% @: J
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); ( V2 \* _9 n8 I& {( d7 g/ K/ a
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
! Z+ G2 [* F5 A% x0 v D- Q |3 q83 sum -= delta; 2 G u: h5 @+ C
84 } /* end cycle */ 7 l* @* U2 @4 l) @
85 out[0] = ntoh(y);
+ c' A" R+ @1 u- T$ O$ [86 out[1] = ntoh(z); ( h0 R" S8 A% A7 ^
87 }: t0 _1 ]3 r* N' c
. E% Y: `* w& D8 d# p需要说明的是TEA的构造函数:
/ [7 j7 Z4 t' h2 ~TEA(const byte *key, int round = 32, bool isNetByte = false);
( O# H( J9 a/ t1.key - 加密或解密用的128-bit(16byte)密钥。
5 ?' B4 ]( b: }! V2.round - 加密或解密的轮数,常用的有64,32,16。 & U3 B# m8 h, Q; r5 ]9 q9 C5 g5 u
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! 7 Q8 w; T( _" s' n4 F0 b$ S0 }
1 F7 u. d3 A" l' Q: v( Y5 g
最后当然少不了测试代码: |
|