|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
& ]- `$ I* Y; v" T/ p* f 2 #include <cstring> //for memcpy,memset 8 r0 x6 Y7 D& I* R" U8 S) P
3 * j4 I! R# k/ M
4 using namespace std;
* V1 u/ ] U: [ 5 6 u, h" A0 D; s5 J+ }
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
' t/ q! ^, B6 [0 p 7 :_round(round) . B3 T6 l f) N' A
8 ,_isNetByte(isNetByte) {
C# }9 a/ d" P 9 if (key != 0)
5 R7 D7 z2 S% a; ]5 n4 |9 e! O10 memcpy(_key, key, 16); 6 l" g& j ^$ ]. K/ s
11 else
# T& u% w* Z5 i$ G# U" P5 M3 w12 memset(_key, 0, 16);
6 L8 u! [0 |+ v+ U0 }7 c13 } 1 _8 z5 H# N/ y( |5 M6 }; h/ H
14 2 F, w! m$ F) ~! ?' i
15 TEA::TEA(const TEA &rhs)
+ J% C0 a9 a( V16 :_round(rhs._round)
% [3 B2 @; a, G, I X17 ,_isNetByte(rhs._isNetByte) { ]1 o* z, V# w# K
18 memcpy(_key, rhs._key, 16);
, a3 }# z c# Y$ t& C3 N) Q; e7 F19 }
5 C- X3 u+ |5 m9 _9 C" b; a9 S20 4 R& R/ {/ w/ i
21 TEA& TEA::operator=(const TEA &rhs) { 3 i& c, @8 A) L
22 if (&rhs != this) { 3 ^6 d4 K2 X. q6 q: _4 m8 G
23 _round = rhs._round; 8 w+ x6 n" l) r& a2 n2 ~) g. t: S
24 _isNetByte = rhs._isNetByte;
0 L) v- n& J" v6 o25 memcpy(_key, rhs._key, 16); , W3 a% ^4 }* ]. |: M7 ?
26 } # b! M2 j: h% j# ?! e% [# R3 \
27 return *this;
C/ e; t. G. G" S28 }
% {3 I/ l) g6 G& y29
( z# Z8 A' Q0 E* T7 I30 void TEA::encrypt(const byte *in, byte *out) { ( U, e* M, B; [9 Q8 ]+ U. P
31 encrypt((const ulong*)in, (ulong*)out); " |8 C# B' W5 l! q( K6 E4 }7 y
32 } ! w4 D, @' j( ` Q
33
: U2 z5 n- S+ R0 J! {* _! M34 void TEA::decrypt(const byte *in, byte *out) {
2 X- ?5 m7 r7 }; E3 _* n35 decrypt((const ulong*)in, (ulong*)out);
% [' p9 g7 t A! X36 }
$ |, ?: z. O; }, k8 m0 [' _( m37 , J! ^* j- ^* ^3 h
38 void TEA::encrypt(const ulong *in, ulong *out) {
. r9 [' K f; V# q* D0 y! o) ]- P39 ; Q4 U' e/ X4 B3 d, `1 Q
40 ulong *k = (ulong*)_key;
5 w* w0 ]" j- S' ^ r# A( P41 register ulong y = ntoh(in[0]);
) k* M; L- x" S- {; _42 register ulong z = ntoh(in[1]); ; D. w6 B0 i1 o
43 register ulong a = ntoh(k[0]);
$ `2 z9 W1 H; {+ `8 \44 register ulong b = ntoh(k[1]); H- B7 H& O- g
45 register ulong c = ntoh(k[2]); ) I; ?2 \% \6 F3 n0 ]2 X8 O
46 register ulong d = ntoh(k[3]); + E$ C5 \) L+ d4 e- T* U% G* }
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 3 x2 T$ }" H) d9 u8 C8 J! e9 J; m
48 register int round = _round; ; D# r+ k0 `3 k# O# l, Q
49 register ulong sum = 0; 6 q \4 n0 V. g5 X) m4 U. d
50
0 {' m9 g+ ] c3 n9 {7 S51 while (round--) { /* basic cycle start */ $ @) Q7 \5 B! }: {% a9 B
52 sum += delta; 0 K n3 b% M$ J6 N9 H$ M! \
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
- F3 r+ c$ E/ i% B54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); % b; W( l3 ` O0 s% ^
55 } /* end cycle */
8 j1 W3 L5 I; M2 _' ~# m& T56 out[0] = ntoh(y); 2 ~$ U4 J/ K) p- a( R
57 out[1] = ntoh(z);
1 Q4 O9 k& }. U) J2 d+ ]; e0 T9 z- {58 } 1 r* u: e: R& p& \2 Y9 S9 o
59
$ ]8 ]1 W, h! |- B& n+ Y60 void TEA::decrypt(const ulong *in, ulong *out) {
1 }9 _7 f e" R4 a4 T61
# D2 {/ m% Y% H* f& o E5 s# G62 ulong *k = (ulong*)_key; 6 F+ a: n6 ~1 n$ j' a7 T1 A
63 register ulong y = ntoh(in[0]);
; R8 [% c+ {/ F8 t; I64 register ulong z = ntoh(in[1]); [4 y0 `- Y6 r
65 register ulong a = ntoh(k[0]); * p6 l J+ T7 [- q+ y
66 register ulong b = ntoh(k[1]); z* }, p% ~5 G8 s/ u1 ^
67 register ulong c = ntoh(k[2]); 8 y$ h. j K. L, Q
68 register ulong d = ntoh(k[3]); 9 g0 u. z6 g6 b. D
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 6 O6 a9 ^: u: m4 N+ [- [& ^
70 register int round = _round; 6 \' r' Z% L* b$ O; m2 X
71 register ulong sum = 0;
; R2 X9 l( D) z: e. q1 @72 + W# `; U4 O1 }" z. y, l
73 if (round == 32) 0 Q$ b! ^8 `8 H' {, D
74 sum = 0xC6EF3720; /* delta << 5*/
) }" u7 B* `2 S75 else if (round == 16) % {- _* r$ h' |" H# ?
76 sum = 0xE3779B90; /* delta << 4*/ . H, V3 i3 d6 K9 P% y% q
77 else
# M0 q1 ^ D4 B78 sum = delta << static_cast<int>(logbase(2, round)); . i- Y; _, `" ~' R+ T# b& M" m
79
/ x! Q ?* R, j6 v0 U2 l80 while (round--) { /* basic cycle start */
# T4 B, a6 n- C0 X; }2 {0 E6 E81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); 0 b @8 [2 J, ] q9 N0 l) n+ B
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); % o) G) ]# B& h y6 a O i* I% @
83 sum -= delta;
$ @- Z9 I m" p8 j84 } /* end cycle */
$ i4 q# b9 \2 O3 B3 m% v! I: I/ C85 out[0] = ntoh(y);
* J$ }9 l9 d, e+ I* `+ X. p" p86 out[1] = ntoh(z); * p8 V4 T2 h% s7 f! M: o
87 }, S6 i& E2 E$ M2 P, }
# N. @* H3 q" x A& Y) |! P$ {9 V& [7 c
需要说明的是TEA的构造函数:
6 m: ~2 k- t% H' a! ^% MTEA(const byte *key, int round = 32, bool isNetByte = false);
1 @5 V) u: W! D [7 y+ L1.key - 加密或解密用的128-bit(16byte)密钥。
. [: v" D# W9 x5 r2.round - 加密或解密的轮数,常用的有64,32,16。
+ y5 }+ r5 `1 Q: O2 H0 l2 @3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! 7 B0 {# s1 G: P
& c6 G6 E6 A# o) E& M, e9 F7 @
最后当然少不了测试代码: |
|