|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
. ^% \: a0 ~; u% }9 \ 2 #include <cstring> //for memcpy,memset 4 x/ H3 q2 i8 n; ?7 o
3 / ~* J+ e8 `& Y. [+ ?$ e( q; A9 i7 k3 M
4 using namespace std; 6 i* ]( a9 J. ]! H; U
5
0 Z5 }$ [1 q& U; O F9 j8 H' U 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
: N7 J/ _3 ^* {- N( Z$ [2 L 7 :_round(round) 1 U# k8 v1 @) Y7 ^' ]7 U: v4 f
8 ,_isNetByte(isNetByte) {
/ c8 v- _5 j1 {' F* o 9 if (key != 0) % H/ \3 M, ^$ S; E$ T0 K
10 memcpy(_key, key, 16);
1 G. X$ r+ ~& R4 P6 S7 z+ z2 Z11 else ; |* F( ^; [2 J( q) t
12 memset(_key, 0, 16);
- ?# I7 Y' A1 K13 } + l6 S/ t0 ~& m' A' c+ g
14 : Q; T" |1 Q: q5 @
15 TEA::TEA(const TEA &rhs)
& Y+ c4 a, l/ ]16 :_round(rhs._round) 9 t$ @0 W4 R" g; K7 u5 `
17 ,_isNetByte(rhs._isNetByte) {
% W7 y" ]" d/ J! I/ p18 memcpy(_key, rhs._key, 16); 6 d8 c7 {* V8 h6 _
19 } 8 r. _! m) d, e0 I2 M
20
9 t6 `! {6 G3 u& K6 C21 TEA& TEA::operator=(const TEA &rhs) {
- K$ I1 D0 H6 F9 J& x. {22 if (&rhs != this) {
* R. t; x( P; @% Y23 _round = rhs._round; 6 `( V# I4 p# \, w7 _: f
24 _isNetByte = rhs._isNetByte;
& A8 d+ M5 t7 V: ] v" j" R25 memcpy(_key, rhs._key, 16);
. U- g! w" F; c) T7 y26 }
6 H9 V( Y/ \0 {5 x27 return *this; 9 R$ ~4 |; ~: X+ o/ j }
28 }
$ q5 n2 g/ i3 X b" V0 ]29 - j, x Q0 f" V( b
30 void TEA::encrypt(const byte *in, byte *out) { $ ]4 F4 R' e! R- v/ i$ o* C
31 encrypt((const ulong*)in, (ulong*)out);
. M- F# g. X g% n. C; W32 } % k, e! x/ [' r; }
33 5 B, H7 n+ ^- v+ E4 J" Q6 B
34 void TEA::decrypt(const byte *in, byte *out) {
; G% m( } ?( D35 decrypt((const ulong*)in, (ulong*)out);
& j6 z4 V% I2 ~" ~3 Y, y) a36 }
5 P' _* b5 z2 [0 r/ b I37 . @- c# j6 d9 g$ b: q2 [5 N* R
38 void TEA::encrypt(const ulong *in, ulong *out) { " C. J5 |$ P; P9 G g) U
39
+ @ @3 Q$ |2 S) q: V: B9 M6 m- C40 ulong *k = (ulong*)_key; ! L' I1 B2 R+ s2 {
41 register ulong y = ntoh(in[0]);
3 B& g* q3 P% d- A42 register ulong z = ntoh(in[1]); $ j$ v' J& S" l7 _, P
43 register ulong a = ntoh(k[0]);
! b! \3 Q/ S$ Y& B, Y: X9 ]) n44 register ulong b = ntoh(k[1]);
" v; _' M! f3 Z& b: Z# o/ F45 register ulong c = ntoh(k[2]); ]3 `! Q) d2 _' Q
46 register ulong d = ntoh(k[3]);
$ T$ r4 _& N3 u3 ?( S4 @47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 5 N5 C; _1 K" w* R' e1 `
48 register int round = _round;
1 b- D$ y: d* T0 \2 O: j49 register ulong sum = 0; 5 Z/ b' Q4 u0 X. s
50 1 Q" R, z( ~1 Y' g5 j" n4 i% z
51 while (round--) { /* basic cycle start */
* S+ y/ p0 W/ j5 p/ [2 y52 sum += delta; # U( u6 e T* o+ o9 U
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); ) @0 ^8 d5 ~* X7 T8 v3 H
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
l! @& ^9 q8 |* j$ z* Z- }" j+ U55 } /* end cycle */
7 s) D1 ^8 u6 ~3 ?- z56 out[0] = ntoh(y);
' G z& `: h; X( z* Q/ Y57 out[1] = ntoh(z);
4 a) ^- A& W% w8 T! n58 } ; K7 w2 Y% m6 a, P( t
59 & Q% B8 M' W- @' @% L) K
60 void TEA::decrypt(const ulong *in, ulong *out) {
, C1 _8 R; @, r( l6 M$ c$ `61 . P% V8 k1 @7 v' Q8 M- d, |# n3 p8 r
62 ulong *k = (ulong*)_key;
_1 p+ C% _7 M* B- B0 V+ T63 register ulong y = ntoh(in[0]); : `& \5 o) J- c( X) {
64 register ulong z = ntoh(in[1]);
+ R/ e9 `) x3 l65 register ulong a = ntoh(k[0]); 5 W% Q# c' t. D5 C& m
66 register ulong b = ntoh(k[1]); % I0 W& ^: b$ D+ {
67 register ulong c = ntoh(k[2]); # K" I9 j( |, d# W. N- U; N" |' Q; H
68 register ulong d = ntoh(k[3]); * ]5 O: C. V0 O7 q5 s' Y5 j
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
/ X3 l5 n. z. I70 register int round = _round; f# Z+ L* [: N6 z
71 register ulong sum = 0; + @% e2 A" N& I5 o( y7 g a+ Z' H& E
72
. c+ H9 @ |9 A0 \7 {# {1 z5 K. u73 if (round == 32)
3 D3 P8 W8 F+ w2 n- I74 sum = 0xC6EF3720; /* delta << 5*/ }* V$ Y0 s S: s2 h
75 else if (round == 16)
9 O m4 q0 e. S, ~. H0 S$ g76 sum = 0xE3779B90; /* delta << 4*/
* R. o; x" A; ]3 p77 else
5 Y2 w4 C% m7 b: _1 r78 sum = delta << static_cast<int>(logbase(2, round));
" `1 H: S( Z* J7 \79
# ~. Z! i6 B& m& l80 while (round--) { /* basic cycle start */
- ~3 d. u8 \% Y7 l# H81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
7 |5 k7 {- D- f+ |1 @! q82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
h7 s$ Z& a4 }; P! V+ Y/ f83 sum -= delta; + H. a' f: o2 z" I6 S* |' u( y
84 } /* end cycle */
' `/ L2 C+ O- n' O, X: K+ ~85 out[0] = ntoh(y);
/ I& n3 E# @9 t% s) _86 out[1] = ntoh(z);
. a( c; \& t8 z- w P87 }8 V d. ~! i( m8 e7 f; O' n& n
$ ^! U5 r0 R; X
需要说明的是TEA的构造函数:
0 F. ]& Y0 i& ?, i9 A" k9 e1 S. VTEA(const byte *key, int round = 32, bool isNetByte = false); * F1 ?) Q, C$ z: }/ s8 j) l
1.key - 加密或解密用的128-bit(16byte)密钥。
2 S0 N, z- g! {! E( g9 B2 |2.round - 加密或解密的轮数,常用的有64,32,16。
: c: B8 {; o0 ` |+ u7 c( N6 h4 Y% u3 S9 d3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
/ e4 h, p k+ M0 e8 p* s: o9 B1 C
最后当然少不了测试代码: |
|