|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
6 I& M' @* c3 } P 2 #include <cstring> //for memcpy,memset
4 c) V K5 C! { L 3 + o6 K2 h1 ^5 v/ Y* O
4 using namespace std; $ k; N7 Q6 V3 I/ a
5 % ?! v8 I2 L W: W4 u/ p5 U
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
b/ n! L+ M, c 7 :_round(round) 5 _- D: A, H2 M" ^" n, R9 r; o7 F
8 ,_isNetByte(isNetByte) { . s i' T, ]5 Q4 H7 k/ c0 Y! F) F
9 if (key != 0)
9 u9 ?% Q" S; E: C" z5 q* h* i10 memcpy(_key, key, 16);
/ j' T) e: g0 B5 ]11 else % o1 U. B2 _! c3 W# @5 r
12 memset(_key, 0, 16); - L3 k1 T k% q3 v( W/ Y
13 }
3 ^! U' y0 _0 H5 g# D" N14
" C# j7 J1 R L; o3 N1 M) w/ |8 k15 TEA::TEA(const TEA &rhs)
: m0 l E1 ], E3 i- ?16 :_round(rhs._round) + F; M$ k0 f! x7 L: M, u! J6 h
17 ,_isNetByte(rhs._isNetByte) {
7 T4 E1 u4 W o+ S' E0 \18 memcpy(_key, rhs._key, 16); f: |; T; t# C6 _0 g3 c
19 }
/ p0 F! y+ ?" `- X T( {20
; A6 N% Z9 x. f! J, E$ @- u, p21 TEA& TEA::operator=(const TEA &rhs) {
# r9 c; \% R- e. g* v" f; \- {22 if (&rhs != this) {
' z8 g% x0 P& L) N: A8 c23 _round = rhs._round;
4 V* x6 h, c8 i: E1 m; }24 _isNetByte = rhs._isNetByte;
1 [* P; ~( \/ } g4 T25 memcpy(_key, rhs._key, 16); ' D4 I' E6 s2 V
26 }
6 o- V0 W' ^" d5 i, Q27 return *this;
' C6 f, P6 o: {/ K- C28 }
' H3 o0 s3 {) I7 z% o8 v% [29 5 ^7 Y5 e. d& D- i
30 void TEA::encrypt(const byte *in, byte *out) {
; f2 K$ A! I6 h2 `31 encrypt((const ulong*)in, (ulong*)out); $ n% o+ o3 K7 G9 d2 t3 r
32 }
5 D F D& l+ P6 y* }3 }33 , _+ B7 a9 e7 k7 j, e! T
34 void TEA::decrypt(const byte *in, byte *out) {
& d7 V6 X- D! u+ Q35 decrypt((const ulong*)in, (ulong*)out);
( l/ J6 z9 \- V9 d1 Z36 } # s3 I7 X5 H V, k. z- p, ~
37
. ?$ }0 A! [ I9 l: ?* r( L38 void TEA::encrypt(const ulong *in, ulong *out) {
/ g2 y1 }' R5 c39 % a F. k3 K; h5 k5 i7 h
40 ulong *k = (ulong*)_key;
$ t; e' @, G5 @3 B2 ^- X41 register ulong y = ntoh(in[0]);
3 v c2 `% J( z, W2 C" K42 register ulong z = ntoh(in[1]); ]7 b+ i& Z# h+ _
43 register ulong a = ntoh(k[0]); / u5 ?: I; A" o- @! E
44 register ulong b = ntoh(k[1]); g/ K2 @( ~/ p( F0 N, ?4 d
45 register ulong c = ntoh(k[2]); . _5 q5 K2 D: u2 a! @
46 register ulong d = ntoh(k[3]); 7 z- o$ ?. K' S. U( j4 i3 d/ d
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
9 _+ {5 ?# F- m# C+ i" @) }48 register int round = _round; ( D' j& T' Z& O: l+ n
49 register ulong sum = 0; % p/ ~% I6 V$ X5 S7 s, r% c- n
50 - ~3 j* {) n9 f/ H4 u, m
51 while (round--) { /* basic cycle start */
" `9 Z/ v( e7 A# f52 sum += delta; % r) t8 o. i1 D2 p- ^
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); 6 X4 u0 z- n) \4 G. g
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
: n, ]8 `/ [, ^7 s7 R55 } /* end cycle */
( B1 p) u7 t, f0 L56 out[0] = ntoh(y);
# m2 O. j* }' D: i+ |& f4 }57 out[1] = ntoh(z);
* t! {, |3 g+ Y' U1 Z+ R58 } * K G, m" h! _
59 " r7 x' P6 R4 C9 W% `1 U
60 void TEA::decrypt(const ulong *in, ulong *out) { 8 i1 R5 r1 V+ @
61
$ B4 i9 l1 D: t, d" X o1 k% q# V/ @0 ^62 ulong *k = (ulong*)_key;
" {9 B2 @, C% ^7 Q( D63 register ulong y = ntoh(in[0]);
- e& Y& R4 S) K" i64 register ulong z = ntoh(in[1]);
4 S( y5 h6 R p/ o/ ]% f* I65 register ulong a = ntoh(k[0]); ) J. X2 X4 Y* V6 w" @5 q
66 register ulong b = ntoh(k[1]); + [3 c1 T$ Q3 K# ~7 W
67 register ulong c = ntoh(k[2]); : \0 T3 k1 g. G7 S/ P& X5 k9 J7 ?& K+ s
68 register ulong d = ntoh(k[3]); ( p0 X$ ~, g" d( b
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
& v b& P0 |3 |: n2 s$ y70 register int round = _round;
6 | ~0 t% `. G& U1 F* b71 register ulong sum = 0; 9 G$ c2 e9 k) H/ U/ H- p$ v
72
+ O K+ V) T* ?! y73 if (round == 32) $ X6 o, F7 q3 m+ k$ K6 W# ?
74 sum = 0xC6EF3720; /* delta << 5*/
% N# [( a" C( I3 A4 j" O \5 U75 else if (round == 16)
8 a' p. U( V6 ?0 k8 T2 O4 s76 sum = 0xE3779B90; /* delta << 4*/
3 P1 ^1 y- U1 y77 else
+ }2 h- J( A6 k78 sum = delta << static_cast<int>(logbase(2, round)); . w r6 s& Q) l' \, |5 M& ~
79 $ w' ~" W! U! V% _
80 while (round--) { /* basic cycle start */ : G. W! s3 y9 b _2 Z& K |
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
$ p4 [: y: l* y4 o; A- L82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
- e+ b( M: H' H6 E9 {83 sum -= delta; , z' ~ b) {; M& e1 u
84 } /* end cycle */
s9 K7 h. S) P* m% p85 out[0] = ntoh(y); / N* B3 S5 {/ A, Y; F$ E) t8 y$ ?
86 out[1] = ntoh(z); % o9 s6 I8 r, H% e7 N. p7 ]% c; z
87 }
7 U" r$ b+ I. T7 a2 \0 {! {) d0 N1 n/ d( U k/ |
需要说明的是TEA的构造函数:
. G* F. ]$ d( YTEA(const byte *key, int round = 32, bool isNetByte = false); ( N4 U+ t3 p/ L. {
1.key - 加密或解密用的128-bit(16byte)密钥。 / C; D0 m1 e9 }
2.round - 加密或解密的轮数,常用的有64,32,16。
3 o+ x9 C- ~) {" J3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
9 E0 _, [9 Q; ~, m! U$ K
$ |4 u* r/ I$ i9 F; D: H( V6 f2 Z最后当然少不了测试代码: |
|