|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
- ^$ a+ D# d' J" H" Q* J% x 2 #include <cstring> //for memcpy,memset
( I) t. e5 @3 b- E9 A 3 2 @& e, {, U9 |1 K n- C( t
4 using namespace std; ( C/ e/ D" g1 s+ m: r; W
5
1 D5 F) ]/ X/ D. ?; o 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) $ i$ [1 W( j" c% c' D) W2 z
7 :_round(round)
: _0 K2 y! k0 M; H/ `2 ]. t+ D 8 ,_isNetByte(isNetByte) {
) ~* I* P- s( t 9 if (key != 0)
{8 L" ]& _( v. q0 u10 memcpy(_key, key, 16);
2 N x6 n- ` W" [% K11 else
: k$ Q$ _; |9 T' G4 E4 ?12 memset(_key, 0, 16); 1 l3 _, W _+ { |( K+ m
13 }
5 M+ G- K! K& d14 5 U0 B5 p0 \, q) |
15 TEA::TEA(const TEA &rhs) % u: H4 ]# b G9 Q7 |$ W" U
16 :_round(rhs._round) % q0 f+ G$ \ m) w0 e
17 ,_isNetByte(rhs._isNetByte) {
1 c1 I' u0 ?: F5 K18 memcpy(_key, rhs._key, 16);
6 w9 v. O% j* W$ G) ~7 @& X19 }
, D. U' }9 k6 `% H6 m20 1 t1 O. V& ~' V) R6 k
21 TEA& TEA::operator=(const TEA &rhs) { C1 j( e# X9 `1 q/ _. O
22 if (&rhs != this) {
2 I, ]8 e" v: m* R; a" |23 _round = rhs._round;
3 P7 W6 t* q: [24 _isNetByte = rhs._isNetByte;
* q! D0 i l5 T" j25 memcpy(_key, rhs._key, 16);
7 A7 X$ m( e9 T2 k6 A$ z26 } + T! C5 x$ p7 a# ~5 O
27 return *this;
2 E0 u$ H% y! V28 }
( d' D, Y2 m5 M( h0 O29
3 V0 ^0 Y) f/ i/ x9 p1 o/ o0 d30 void TEA::encrypt(const byte *in, byte *out) { ; S, K( a/ x4 ^4 F e& l5 w
31 encrypt((const ulong*)in, (ulong*)out); 1 F* {8 j+ u1 h+ {- t/ K& E' m
32 } / d3 p% i8 l; t1 H# o) @/ P
33 % b _" b3 j/ G( f- ~- J0 [
34 void TEA::decrypt(const byte *in, byte *out) {
w( s# K0 Y0 r$ E. ~( Y35 decrypt((const ulong*)in, (ulong*)out); 8 ]9 M9 T% A, @% ~
36 } 9 l& f! y: b/ [$ Q5 ^) Z& K6 `
37 ) T5 a- K+ R# t* _0 q
38 void TEA::encrypt(const ulong *in, ulong *out) { * r0 E' c1 E5 N6 H, Y: ~% U
39 7 h( `2 M0 M% l0 X% \) W8 F* R
40 ulong *k = (ulong*)_key;
0 j. K% I6 X# x' d; v9 t- c41 register ulong y = ntoh(in[0]); L1 Y% w; Q9 @) p: L _; [
42 register ulong z = ntoh(in[1]);
* o8 z* v3 K5 n4 v43 register ulong a = ntoh(k[0]); 5 g+ F1 C% g2 e3 q( j3 J4 C/ R
44 register ulong b = ntoh(k[1]); ; v" k, ?" |5 v2 [
45 register ulong c = ntoh(k[2]); # T- f* D, T/ o, q" W5 m1 Q
46 register ulong d = ntoh(k[3]); : l) l6 z/ G }) l) r, {$ C$ p2 E! U
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
6 H/ U; x. d# R2 z48 register int round = _round; ) j/ ?- d% o3 |4 G% [2 Q/ m
49 register ulong sum = 0;
' M2 U. @' r. `; ?2 _50 # U0 |, W3 P3 k) e
51 while (round--) { /* basic cycle start */ ! s, J) F, h. l8 d
52 sum += delta; 7 M: i- T- o4 D& `8 F; |0 B
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
+ ~: B: S# j' {5 w [ n( e% W54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
" N) L# t' X. t55 } /* end cycle */ + n- N `6 P) D, C
56 out[0] = ntoh(y); & Z( I4 `3 O& |; _/ k
57 out[1] = ntoh(z); 4 D4 Y# q6 j8 }, b2 D
58 }
/ R' @; W9 I$ `* f+ \2 P59 8 R( [' r& e* D; V3 ?) o0 W% g$ `
60 void TEA::decrypt(const ulong *in, ulong *out) {
$ S0 {7 F! D' |# w" z: b" T61 |! e2 }& _7 t' Z/ b0 O
62 ulong *k = (ulong*)_key; ! _; d$ W4 w6 w# M) [* q
63 register ulong y = ntoh(in[0]); # T, N# r% R5 S! w4 M
64 register ulong z = ntoh(in[1]);
5 H+ L1 ^, I$ T& b65 register ulong a = ntoh(k[0]);
" l5 s3 i7 C4 K) Q) [/ }' H# W9 I66 register ulong b = ntoh(k[1]);
/ A( }6 x& U" U% y+ N; e67 register ulong c = ntoh(k[2]); - t1 K$ L0 \. F) t0 @% W6 P; `
68 register ulong d = ntoh(k[3]);
+ o% H( \. W; ~; c- P69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ " ~8 |" c$ t9 C* S2 l9 D
70 register int round = _round;
7 g7 e$ n) @3 o) q; w5 d( b% e71 register ulong sum = 0;
6 R# r# i4 L1 K1 Z* x. p/ _: j7 \0 o8 ^72 2 v: l( D0 f6 ]/ T, N
73 if (round == 32)
% w9 x, O6 F/ s2 g74 sum = 0xC6EF3720; /* delta << 5*/ - G0 @! C! ~( t8 s& M5 ~
75 else if (round == 16)
+ {( V/ R4 e. h1 g76 sum = 0xE3779B90; /* delta << 4*/
7 c: K- r$ _, c. H+ B77 else ) d6 J, K7 n5 k( U
78 sum = delta << static_cast<int>(logbase(2, round)); ) \, n% i( g! ^0 n4 ^8 ?
79 # U1 K/ O5 l" Z+ F1 g- s: [7 q; I
80 while (round--) { /* basic cycle start */
9 M* D: w1 f; u0 `7 ?81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
7 C( o \9 N- Z2 u- F82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
8 b2 e$ c( c9 y* t4 H# ^; N3 u: k83 sum -= delta; $ R7 l& M" l8 F8 p
84 } /* end cycle */ , q8 Y+ B' B9 Y2 q! A
85 out[0] = ntoh(y);
& E0 _( \% d2 Y0 j7 `86 out[1] = ntoh(z); 3 s, V: `! B' d
87 }
5 G* O: O& w! | b- t5 ]
% v5 _2 A; }. |& d# U需要说明的是TEA的构造函数:
; u: H5 J, m7 |! B, ~TEA(const byte *key, int round = 32, bool isNetByte = false);
' H& j% q% n* D/ Q1.key - 加密或解密用的128-bit(16byte)密钥。 . u" N L; s r/ d8 q
2.round - 加密或解密的轮数,常用的有64,32,16。
/ T" h" y# E; i+ g3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
3 k' ~3 M6 a# R& A" G9 [0 v% a |1 R V$ ~; R- O2 p( R( P6 r
最后当然少不了测试代码: |
|