|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
) Y3 ]3 t H% |$ P6 i( { 2 #include <cstring> //for memcpy,memset
i9 U" j3 e5 R1 @+ }% ]. G 3
6 [" L* F. F& Z5 s1 g 4 using namespace std;
8 e w& M) p( x- U6 L" {# ^ 5
" `0 A9 x, L8 E1 X7 C 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
K9 y4 r4 \& Z, i- D; O 7 :_round(round)
~: |% E6 F/ T( t/ [ 8 ,_isNetByte(isNetByte) { 4 p. g1 E3 U4 l A& `
9 if (key != 0)
; y7 o b' y! F10 memcpy(_key, key, 16); ' H* T }, s6 h! b4 O% \, M
11 else
- {) X( R& u2 l6 F12 memset(_key, 0, 16); ; @" C- `- E, p4 m& p% T* Z' Z
13 }
) c0 Z& c: R% y- T8 l+ }' f7 L14 . }* h) F, f2 D% u5 o5 c
15 TEA::TEA(const TEA &rhs)
6 Q- O( F6 r4 a4 T- D8 { O5 j5 f16 :_round(rhs._round) * R/ g2 q" i/ J0 U
17 ,_isNetByte(rhs._isNetByte) {
3 a) r3 ^2 y4 ?18 memcpy(_key, rhs._key, 16);
# s- p0 [) V- j9 ?- ?" N19 } 8 f _3 H4 b7 g0 P9 V
20
1 ?0 i* m2 K! ?21 TEA& TEA::operator=(const TEA &rhs) {
5 P7 s& b* B1 k, J- `! _22 if (&rhs != this) { $ p8 N! T) W% {' E; B8 m
23 _round = rhs._round;
+ g" }8 v) b B3 O7 n+ I- y" e24 _isNetByte = rhs._isNetByte;
2 E! a( \; [. J: H$ L25 memcpy(_key, rhs._key, 16);
" W+ U7 }! Q! r; y26 }
' D) K5 R5 p" l27 return *this; {6 h6 Y- P. U1 ?/ F$ c
28 }
9 i4 H1 b# S4 u1 S29 @7 [+ B, n" b
30 void TEA::encrypt(const byte *in, byte *out) { * Y! ]# D% Y1 ^7 d0 v$ }
31 encrypt((const ulong*)in, (ulong*)out); + c* O% s/ ~7 q7 ?7 \2 U4 ]
32 }
) J9 a9 [# ]2 I7 C* c6 e33
# k4 F. `( j3 J: k* k% S34 void TEA::decrypt(const byte *in, byte *out) {
+ Q# W# p% q6 m) e# m) q35 decrypt((const ulong*)in, (ulong*)out); 4 ~" U' J% M+ t* ]! K# F7 V* T- N
36 }
}7 [' @& d/ G- ]5 _: V, i1 m1 g) {37 8 p1 Q i1 p+ k0 U. I* P
38 void TEA::encrypt(const ulong *in, ulong *out) { + Y; y+ E' Q; i b4 {
39
- w6 v0 Y4 f; \. F; o. T- v- y, J7 Z0 Y40 ulong *k = (ulong*)_key; + x$ d' i; g/ n5 }- a$ R+ Z
41 register ulong y = ntoh(in[0]);
' O) i+ Q. w" x4 O+ ?42 register ulong z = ntoh(in[1]); " r0 O( d. z* R: L% W
43 register ulong a = ntoh(k[0]); }3 R+ ?/ }7 o/ J' o
44 register ulong b = ntoh(k[1]); 4 R! J8 p0 [& x6 o( q g. p- S& E
45 register ulong c = ntoh(k[2]);
' N2 }+ J+ k; A/ k) h k46 register ulong d = ntoh(k[3]);
+ n g) G8 Y5 h" J5 ~" P- t47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 3 h/ I% ~& G/ ~5 c- w
48 register int round = _round; * N1 l+ e3 D9 C' Y
49 register ulong sum = 0; 1 J; v% w1 a S$ g! d4 Z9 _9 W. F
50
' K( Q; W) Q5 y/ {' }51 while (round--) { /* basic cycle start */
# X* |; |6 y/ X$ Z$ G/ P52 sum += delta; + {2 D& J/ u4 H- O" L0 C0 V U3 G
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
$ R7 H' L6 t3 r$ A* p" ^( G54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); # c6 m( Z% L# Q6 \- r) _
55 } /* end cycle */ 0 g2 g- Y! a* L1 `% } {' j$ N
56 out[0] = ntoh(y);
; m. X( G9 l6 k- h4 W57 out[1] = ntoh(z);
$ y3 ~9 w# t7 }) @8 `$ O2 I# O58 }
$ K. j( V! z4 c. y% {" u59 * L* F7 h! U+ _) z: E6 ]+ `, {" u
60 void TEA::decrypt(const ulong *in, ulong *out) { 0 F6 K7 S m* J# T% w) y9 \
61 5 G3 S' G G1 J2 N( e
62 ulong *k = (ulong*)_key;
3 o) l( T9 {* R) [. b63 register ulong y = ntoh(in[0]);
; S. j+ ^7 \5 X" F64 register ulong z = ntoh(in[1]); / _( |* a" B. ^0 r. {) G
65 register ulong a = ntoh(k[0]);
7 ]/ C, w1 ^( r7 j! o) I) ?7 l0 v66 register ulong b = ntoh(k[1]);
& @% X# y# o9 o+ I- y/ G7 I' }- w- Z67 register ulong c = ntoh(k[2]);
! `& }; Q, V: k1 }# Q4 B0 K68 register ulong d = ntoh(k[3]);
# H5 j" y; x! W$ S4 Z1 @8 B" B4 L69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
8 j9 N) O2 {9 e1 q) O70 register int round = _round;
/ q' V1 A" X S( g7 Q71 register ulong sum = 0;
7 H# b! o9 Z z' P7 R" ~, d2 `1 I3 ?72 3 f/ l, U+ ?; M; I% P
73 if (round == 32)
( C' {/ H' [8 L, v& o0 Z74 sum = 0xC6EF3720; /* delta << 5*/ 9 G% k+ H X$ ^% }7 a: y' }# s! l
75 else if (round == 16)
' C; y7 i. s _! @; p76 sum = 0xE3779B90; /* delta << 4*/ ( A2 |+ {8 V: B6 y0 U8 H
77 else
6 \3 j* h1 j R; }; d) ^9 z78 sum = delta << static_cast<int>(logbase(2, round)); . y/ A0 x. Q4 V2 `: _6 u
79 9 ? l$ x: R7 l! Z5 d3 a
80 while (round--) { /* basic cycle start */
# E/ a- c/ q6 [1 Z* R) u8 k! L' r81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); + o7 m+ K1 Q4 X# z# P3 x( Z! z
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); ) \% {' F: L+ F3 q1 s' J2 ]
83 sum -= delta;
& V8 W3 \) }+ A) ]& k& T' A84 } /* end cycle */
0 J! _: A# Y% X% Q: L1 g85 out[0] = ntoh(y); * O: j" h% G) S
86 out[1] = ntoh(z); ( P. C4 f, }4 h/ J% z
87 }
# ~) p; J7 P0 K, a3 Q4 ^) w$ P8 g+ k; g. S
需要说明的是TEA的构造函数: & @5 u1 i9 V, w9 i( B
TEA(const byte *key, int round = 32, bool isNetByte = false); % A! P/ ]8 o B% k
1.key - 加密或解密用的128-bit(16byte)密钥。 , d( R1 D4 u* F! o/ r+ R7 @
2.round - 加密或解密的轮数,常用的有64,32,16。 5 i3 s& O( N; A$ w, O8 ?
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! ( r- ?; V+ E/ i9 ~
& x( D: k! _+ F9 d
最后当然少不了测试代码: |
|