|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
& z/ H- C/ ~2 c( \3 y1 j 2 #include <cstring> //for memcpy,memset
; E j3 d0 W7 U- C1 u& q) w$ | 3
& u7 i5 H2 N7 \& G* e, e# W" c 4 using namespace std; 0 F4 m* n1 B Q1 c2 W2 e% C
5
7 x2 ~" @/ L) J, v) I G, Y' E 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) - z, b% u+ L" I6 ^ u2 G7 Z6 r
7 :_round(round) 5 z& i# V- Q+ n. ?/ Q
8 ,_isNetByte(isNetByte) {
; `' q) X: `( z# d; L 9 if (key != 0) 5 I- `: S; q2 W0 n) o' f$ H! b
10 memcpy(_key, key, 16);
, e4 j0 u H! m3 [6 z9 U11 else
2 ^" |' r$ L" e4 t9 A- l12 memset(_key, 0, 16);
X4 z2 K, F. x3 Z) H6 M4 i7 h& T% S13 } " s" V C' d8 u
14
0 p; a' o1 Q& ?2 R" W/ O15 TEA::TEA(const TEA &rhs) 4 @5 T6 Y& |; L' ?
16 :_round(rhs._round)
3 Z% a/ z. u) }& K" l# n3 U17 ,_isNetByte(rhs._isNetByte) { D% v/ @" O. z6 W
18 memcpy(_key, rhs._key, 16);
8 N4 W, \. u" \, R1 u5 G$ i& h19 }
0 E9 n! x8 @. z& j2 v20
& O- d6 ^1 c+ X/ o6 K21 TEA& TEA::operator=(const TEA &rhs) {
& i2 W6 z" N4 j( f1 u22 if (&rhs != this) {
5 u& |; J' W6 _0 v4 y23 _round = rhs._round;
7 t( n$ p; r \7 Z4 B24 _isNetByte = rhs._isNetByte; ' Y3 U" O; L1 Z2 b. A$ | S
25 memcpy(_key, rhs._key, 16); " j9 f; p# j8 X; q
26 }
1 b W; \8 ~ f0 t1 J8 i6 H8 f7 C27 return *this;
3 w, ^+ f) D+ A+ x6 E8 ^8 V28 } 6 M: a" w" m. ^: W; \8 D
29
. Y: i% @/ f) C2 \) @7 x: \30 void TEA::encrypt(const byte *in, byte *out) {
% M b% _4 m5 _, ~: n2 A31 encrypt((const ulong*)in, (ulong*)out);
6 t m& _* W* a3 |6 [8 z& N7 U32 }
+ a: @$ n8 x2 O! T# V33
( i. {4 o( a2 S" r; w2 P4 h4 y6 a34 void TEA::decrypt(const byte *in, byte *out) {
B0 F" k0 P( m35 decrypt((const ulong*)in, (ulong*)out); $ ~- o0 I: e7 T8 \. `
36 } 8 J7 ?, b/ S$ N- D4 ~+ d
37
2 A/ \" P$ p6 C38 void TEA::encrypt(const ulong *in, ulong *out) { 9 g! m4 |6 P( W7 f9 b6 m" J
39 x% ~9 ^- x. J7 ?* n
40 ulong *k = (ulong*)_key; ( R3 U: `- m* Q% L& f9 Z
41 register ulong y = ntoh(in[0]);
4 g% e5 J( A( H" J2 g* k42 register ulong z = ntoh(in[1]);
1 n! z- T! G% O; w, t& @5 v( ^43 register ulong a = ntoh(k[0]);
2 I; B1 q2 D/ z, y$ G3 M) O+ H44 register ulong b = ntoh(k[1]);
& \; b( Y( x3 G! v# `3 K7 b0 ^45 register ulong c = ntoh(k[2]);
M/ s5 m$ P$ D46 register ulong d = ntoh(k[3]);
/ A2 T' V$ Z+ Q47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 1 m* z' O* Y: x" ]! A' i' i
48 register int round = _round; : g/ C2 p2 N# ?$ d
49 register ulong sum = 0;
2 k, u( r8 V& j7 x7 Q$ e8 `50
1 T1 Q+ P2 H' G9 S; l6 w: `0 f. I# U51 while (round--) { /* basic cycle start */
* O- v: q6 E9 z$ @9 c! _52 sum += delta; 0 a0 M* e0 Y* j7 f2 L
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); % b5 z% Z/ Z! m2 S: W+ j9 ~1 o& ]8 ]
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); 0 g! Y$ V9 Q M1 L4 h1 {
55 } /* end cycle */
2 d$ K; R) q" h! T8 r56 out[0] = ntoh(y); % G0 c5 i) [1 H3 {) S$ Q
57 out[1] = ntoh(z);
3 P- ]* P3 i+ h% Z/ s& p1 V! f3 Q58 }
1 j% o H$ w) `" [59
/ A5 z; H$ F7 i$ E" R60 void TEA::decrypt(const ulong *in, ulong *out) {
7 _( x2 T2 f0 }# a1 R$ [" v' [61
9 i6 @; H6 [) ?* Q* K, ?62 ulong *k = (ulong*)_key; 1 t$ a2 {0 B8 `' u, l
63 register ulong y = ntoh(in[0]);
; d6 G0 B5 v9 Q) J64 register ulong z = ntoh(in[1]); ' E' B: g) b, ?( o* ]
65 register ulong a = ntoh(k[0]); ) ?% [6 L, U1 z* E3 E
66 register ulong b = ntoh(k[1]); 3 D8 l7 m' A3 y+ p) B" ^
67 register ulong c = ntoh(k[2]);
# @- D9 L$ V H( s$ l( p5 r3 l68 register ulong d = ntoh(k[3]);
0 T$ `% w2 Q; w! ^5 u( U+ \6 F Y3 r69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
( I! i, O5 W8 ?: C7 r70 register int round = _round; , Z" y C9 e% p8 J, d" F# T* J2 r7 m
71 register ulong sum = 0;
6 I1 j: Q8 Y0 v+ a7 }72
5 \* @7 X% l1 k) _' N: b. o73 if (round == 32)
& y0 x5 e4 Z' p( a) v74 sum = 0xC6EF3720; /* delta << 5*/
& n+ X8 V$ j8 Q; b$ E75 else if (round == 16)
5 `0 F+ X5 X) W- P5 Z3 b& j( F76 sum = 0xE3779B90; /* delta << 4*/ ' e: k+ ]1 K1 n' }3 K
77 else
5 |4 n# Y0 f8 J0 `5 h+ Y: d6 l78 sum = delta << static_cast<int>(logbase(2, round)); ' t7 s2 f) [' Z7 t3 J/ {
79
4 q1 J3 N9 \8 s% ?5 i. b80 while (round--) { /* basic cycle start */ + ^# M/ ^' G p" C* V
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); . D x0 z5 {) L5 H# R
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); % u A' P. Z/ Z# B4 w5 l
83 sum -= delta;
- V8 S( ^ d+ d. s84 } /* end cycle */
1 v( ?3 N R% m85 out[0] = ntoh(y);
( ^9 y1 ?8 v2 B; n$ Z; h) X86 out[1] = ntoh(z); 8 ^1 A0 S% [* G- j
87 }, ]" E3 \; a2 D# F8 ]5 L
- w( Q+ E! H6 s. V" R/ i; T" p需要说明的是TEA的构造函数: : ?- U" k% ^ A6 J7 W9 F5 C) K
TEA(const byte *key, int round = 32, bool isNetByte = false);
/ n) m7 W/ r$ @; e1.key - 加密或解密用的128-bit(16byte)密钥。 4 T5 E8 r k" k3 k0 `/ _
2.round - 加密或解密的轮数,常用的有64,32,16。 2 X: r6 P o- r' m/ e' Q0 `! ~
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
/ Y5 B1 S1 w% x+ V/ G" u
2 j g- x9 e+ q+ O1 {最后当然少不了测试代码: |
|