|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
2 U: d0 X1 X; E- g- U1 r. G 2 #include <cstring> //for memcpy,memset ' c6 _: H2 {; m. D
3 $ U' n: W: B: y! ]* W
4 using namespace std;
6 G: ?0 Q7 i8 o$ Y, w; c5 c 5
! q, U+ k( U* o9 m 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) 5 c( {' X5 b: i8 S% [6 I3 g- z
7 :_round(round)
) |# L1 W# H% `# s! J2 U 8 ,_isNetByte(isNetByte) {
9 R; ?/ Y9 ?4 X& z9 l' U0 m 9 if (key != 0)
5 U$ m9 i. M8 w# w$ A6 s3 c& |' x10 memcpy(_key, key, 16);
, @* i' s/ B2 \11 else ( n* ?% }& S% @ t
12 memset(_key, 0, 16); r/ F& B: |8 @2 W
13 } * y5 r8 C9 O* ?. |4 ]2 W8 a( g
14
% O' C1 j& H) r. e# w! n; C15 TEA::TEA(const TEA &rhs) 6 n5 l# [$ o9 A1 j$ w- A
16 :_round(rhs._round)
% r2 _4 u1 E8 Y6 j9 q% u17 ,_isNetByte(rhs._isNetByte) {
2 G9 g5 T& Y4 o% `: L( b' a18 memcpy(_key, rhs._key, 16);
0 L/ S9 a+ L" B8 i" q19 }
: q: @( C' d5 l/ L& l7 T# }4 Z* Z' E20
. \- d) ^9 n+ V$ v7 f# x21 TEA& TEA::operator=(const TEA &rhs) { $ {; f# l3 A' v0 a0 j& w8 y
22 if (&rhs != this) { / G* G; ^% P2 K5 k. `
23 _round = rhs._round;
, v6 g( K4 u( N# N& F4 _9 L6 |24 _isNetByte = rhs._isNetByte;
" ^8 K5 X$ @9 I6 l* A3 Q* {2 _25 memcpy(_key, rhs._key, 16); ( Q1 F3 e; }# c, P. L9 Y- o3 f1 Q5 F
26 }
& x' A u* T) @6 g& b27 return *this;
8 e9 w" o1 w5 q9 Z, ?0 p6 Z( Y: a28 } $ Y2 q9 g. u; f8 U0 o* S+ S/ @
29
7 j. A- K4 `3 z1 l7 L: \30 void TEA::encrypt(const byte *in, byte *out) { / }$ v3 ^( G1 D( e: j+ ^
31 encrypt((const ulong*)in, (ulong*)out);
7 f: @; @6 g! B# b% A& B) r7 Y32 }
: |0 y( `; w: D9 y$ A33
0 e" K# U, E+ Z34 void TEA::decrypt(const byte *in, byte *out) {
2 U9 B7 L/ |) ]8 `35 decrypt((const ulong*)in, (ulong*)out); : z9 k3 ?0 \& l( Q0 e4 q
36 }
1 e' Y2 z1 H/ b+ ` b37
. M+ G. ~2 j# f, N* r3 Q: G38 void TEA::encrypt(const ulong *in, ulong *out) {
4 f% m( S5 l# M$ M! U39
" q- ]8 L+ q" u, k40 ulong *k = (ulong*)_key;
! l6 k/ l4 b- D. ~' T( d- Z$ ^0 ?41 register ulong y = ntoh(in[0]);
* M. {* H9 _& d42 register ulong z = ntoh(in[1]);
4 \: R# `: ]; F" u43 register ulong a = ntoh(k[0]); 6 O1 E0 e5 T7 H( Z! {5 v
44 register ulong b = ntoh(k[1]);
]6 f' n- Q& Q Q5 a1 k- w45 register ulong c = ntoh(k[2]);
. T' m3 l: c# ]5 |9 v6 ^8 Y! J% v46 register ulong d = ntoh(k[3]); 9 ^# Y! N+ C% W& Y5 J( T' B- g- s
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ ( J0 r' H: T9 _& ~5 U& m5 u5 j+ R
48 register int round = _round;
0 d( c$ I' N+ y, R& l% b( F4 e3 q$ o49 register ulong sum = 0;
8 s& n0 k9 {8 y9 k- R& C50 , h+ d7 B, V; T5 Y* I% T0 H/ v
51 while (round--) { /* basic cycle start */
$ E# q/ V9 |4 p( Y& E2 s52 sum += delta;
4 p8 f5 x7 j H H4 M0 e53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
3 ]4 e& o, F4 v7 r+ U54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
& Z- k% w9 O6 k7 i& L( w3 \55 } /* end cycle */ * J* P4 [0 J$ X/ [: c4 C5 {5 X
56 out[0] = ntoh(y);
7 U" J* X. o3 w- K: N5 N57 out[1] = ntoh(z);
& m# L1 L8 g4 {9 d# l f# d: u. e$ y58 }
. y3 ?. \4 V" n3 x/ N% m; O59 $ X3 B C" E' R; N" M) o$ h
60 void TEA::decrypt(const ulong *in, ulong *out) { - o$ ^1 ?3 I/ F( Z, f. P' u. _ R
61 . K$ {0 _- i7 s i, y/ K
62 ulong *k = (ulong*)_key;
( l+ [/ w: {( h1 {* z63 register ulong y = ntoh(in[0]); 9 q y' m& X4 F; q A4 c4 d
64 register ulong z = ntoh(in[1]); 9 ~' z, B5 A$ ^% x" S
65 register ulong a = ntoh(k[0]);
, l- x' |) Y# ?+ I9 {! ^3 t66 register ulong b = ntoh(k[1]); 0 g7 V0 x5 y( w$ R. Z5 h
67 register ulong c = ntoh(k[2]); 7 o* A2 Z1 g: J4 {& V/ z
68 register ulong d = ntoh(k[3]); & y# O! ~. `# f/ W
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 4 y" V' ]! R- E( L6 y' N. b
70 register int round = _round;
6 k' J) H; M* G a: e71 register ulong sum = 0;
6 x6 |: T" N2 l2 ?% z72
# l4 I* }! Z+ N! g73 if (round == 32) - l4 H0 w+ F) H; T: V
74 sum = 0xC6EF3720; /* delta << 5*/ 8 w: m+ c, b! w! N6 X0 C j: |+ I
75 else if (round == 16)
3 ^0 [& F" P4 k, y76 sum = 0xE3779B90; /* delta << 4*/
! z1 M* g" _7 Z2 K3 t1 j77 else
( H$ N$ g- L6 U4 @, e' t3 i78 sum = delta << static_cast<int>(logbase(2, round)); / l3 W: y5 A# U" A2 i8 S! W; s
79 % h; X# x9 ~; l8 s: M! H, _3 L
80 while (round--) { /* basic cycle start */ ! H1 x9 D4 V/ C7 _, ^1 u+ K
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
9 [0 Q) l. v. A& E" r82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); & Y* D! V) w3 W" D8 H2 Q
83 sum -= delta; 6 O/ S9 ^4 s+ T; i; W) p
84 } /* end cycle */
$ G& L0 T0 B( M4 G85 out[0] = ntoh(y);
$ t1 C2 J7 j# n& D+ f/ q$ P86 out[1] = ntoh(z);
: E. N2 d; {8 X. j6 y$ k( |87 } Y4 R8 O% K5 M/ q# h
- b4 n" P; i, f% q需要说明的是TEA的构造函数: 3 }- @8 Z1 u* r- r- A/ n7 F1 s
TEA(const byte *key, int round = 32, bool isNetByte = false);
z8 P: A- U, l: I" }0 V8 W! G( u" ~( ^1.key - 加密或解密用的128-bit(16byte)密钥。
J4 V. y* @3 P) d* g2.round - 加密或解密的轮数,常用的有64,32,16。
. Y/ `6 |5 O5 N( y' y3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! ! n8 F# n$ i' s( A+ k
! q, i, h' S) J- K9 n4 `4 d最后当然少不了测试代码: |
|