|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" $ U8 c; f4 V9 S! Q
2 #include <cstring> //for memcpy,memset
% @ }& y7 I" G" s N, c 3
* a5 l2 e+ h o' h) N# p1 {& P. Q% D 4 using namespace std;
) ~" U( P/ H' x' x, w/ q 5 $ O# }& \0 @% V* t6 t
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
% ~( A! r7 @" I% G 7 :_round(round) - w9 r7 k' a6 x; e% v! b
8 ,_isNetByte(isNetByte) {
" m8 d/ Q, R( K8 Z 9 if (key != 0)
# m9 V- ~. O6 W* B2 w9 |' g10 memcpy(_key, key, 16); d: q3 D6 _9 t6 X' J' Q: \ V- g
11 else # s" K4 q4 p0 z, d7 d- M) |2 [
12 memset(_key, 0, 16);
1 q+ x5 k) N& Y) U; A0 @13 } 3 C2 f# L+ I; w( s6 W1 q
14 4 x% [! h3 u- y0 z9 v- o
15 TEA::TEA(const TEA &rhs)
7 Y- A0 g& A; T, g16 :_round(rhs._round)
8 u" W, c% S- b17 ,_isNetByte(rhs._isNetByte) {
5 u7 n7 c5 a/ I ~' b18 memcpy(_key, rhs._key, 16);
# E; a9 ?5 u: }2 f a0 H& n19 } 2 [4 l! H* v1 n1 G( }, a
20 ( w7 A7 w; G2 L5 ~# i; C
21 TEA& TEA::operator=(const TEA &rhs) {
3 x1 j7 S* S/ |( i22 if (&rhs != this) { 8 y0 k3 |6 G6 B6 S- ^; W8 |! m
23 _round = rhs._round; # H( I0 Y5 |9 D; f6 Y+ X; I* g- @7 R
24 _isNetByte = rhs._isNetByte;
. P: v6 S& d* d# O" |25 memcpy(_key, rhs._key, 16); ( w7 ~7 j! F- e
26 }
7 O/ o- [3 @* s$ w" S27 return *this; - ^; j! z1 R( }& t- }
28 }
# q2 \0 n) J4 O) t5 L1 n2 `29 , G, P7 K3 L9 K; E3 b: C7 ~+ l2 s
30 void TEA::encrypt(const byte *in, byte *out) { e1 `' A6 o1 `/ N2 S
31 encrypt((const ulong*)in, (ulong*)out);
* I. P O! j% j+ R32 } ) o; x) @3 s, B% r2 u- R+ x
33
& q- @3 }% A* A8 | L34 void TEA::decrypt(const byte *in, byte *out) {
8 s2 c6 g7 R% }! L8 @35 decrypt((const ulong*)in, (ulong*)out);
/ g' i7 V+ D( N6 p6 Y36 }
1 W, r% @/ r, S( @) V37
% x/ Z9 |" j7 D, } m38 void TEA::encrypt(const ulong *in, ulong *out) { e( g3 F0 L2 l( l0 A
39 . t. i0 Z: T7 j# Q/ D+ k" M, h2 }
40 ulong *k = (ulong*)_key; 7 s$ J8 d# `, p4 j! k
41 register ulong y = ntoh(in[0]);
; L1 H, T, V8 @: X) g" v5 [$ q42 register ulong z = ntoh(in[1]);
# b/ a. ^0 d) `" \43 register ulong a = ntoh(k[0]); : g/ L ?/ ^- e' U% y9 B7 z
44 register ulong b = ntoh(k[1]); " ?2 a; y$ |$ x! x
45 register ulong c = ntoh(k[2]);
* W: T4 P! G2 Y0 e# ?$ G46 register ulong d = ntoh(k[3]); " b1 }: I: b& O, m+ A4 M& }3 @# |
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
$ j0 n: u; P! x" v48 register int round = _round; 2 ^, K/ s7 _, V/ R/ b
49 register ulong sum = 0;
+ k! q1 |1 A- g L$ L6 H. x# n50 2 c2 ?4 t* s% ~4 \
51 while (round--) { /* basic cycle start */ y! c9 {9 O% e w+ |1 X( v
52 sum += delta;
2 s7 B K C+ g O53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); $ Q) e7 Q& o0 [
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
5 k; a! B& }; J ^% @" Q55 } /* end cycle */
2 X7 ]- R" z( ?* B7 E56 out[0] = ntoh(y); 9 N4 Y) h' y0 \7 o0 M/ R
57 out[1] = ntoh(z);
1 J9 X2 _* P% i2 V G4 T58 }
; p- ~5 y7 r& v) j3 v* P59
) W6 h5 ?) o- x4 c60 void TEA::decrypt(const ulong *in, ulong *out) {
. P$ b, D A$ a; b4 }61
) Q( e$ |% k( i; g1 |62 ulong *k = (ulong*)_key;
" t3 k" H7 x: a2 W! I63 register ulong y = ntoh(in[0]); , R' l7 D5 x7 S; }
64 register ulong z = ntoh(in[1]); 6 h9 l! b- }# x. R0 b; d
65 register ulong a = ntoh(k[0]); - ~2 d4 P" o0 e8 I
66 register ulong b = ntoh(k[1]); 0 m8 H1 _5 ?0 F* t5 \5 E8 H) [
67 register ulong c = ntoh(k[2]); ( C% y# y ]# {5 I) E+ i+ E! P8 i
68 register ulong d = ntoh(k[3]);
# e' X5 f/ B1 ~8 D69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 8 B5 ]; R/ U* u: A( ?& s; G2 ~8 k
70 register int round = _round;
( S5 b/ W0 O5 z- L# ~/ H. N71 register ulong sum = 0; - o+ y$ N% h4 L7 }( t# ^1 n
72 " u3 b: m6 N% t. ?( _1 j6 f9 c
73 if (round == 32) 4 B! o+ v$ n$ ?% K0 g& H
74 sum = 0xC6EF3720; /* delta << 5*/ ' \, z( a6 k) g! ^
75 else if (round == 16)
8 r+ l! S$ T/ [6 [6 G+ g- @76 sum = 0xE3779B90; /* delta << 4*/
1 Q4 u' G0 M' I/ W/ K1 |2 e77 else
3 h* b2 { p8 G78 sum = delta << static_cast<int>(logbase(2, round)); * _, v$ A: f6 J& e
79 / g( H" [5 ~/ _" s9 w
80 while (round--) { /* basic cycle start */
; o: V( L5 j% S+ u. p81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); & }9 I7 T% i+ g4 m' `5 q: I8 ?
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
3 m* e1 D+ m, p& M) r83 sum -= delta;
! d0 T8 c! w/ b3 P7 k) b84 } /* end cycle */ 0 ^7 ?+ I3 W6 r R$ s' |
85 out[0] = ntoh(y);
! R% O* S5 S# p. {, |" |+ B3 ~86 out[1] = ntoh(z);
) M1 Y# Y6 G3 [% `2 [/ ]87 }# O; _6 U: J. B' z
& t* W7 e) C0 d2 N8 t6 ~5 ]
需要说明的是TEA的构造函数:
6 Z9 C5 m6 a: c8 Z2 J9 R; N. r1 rTEA(const byte *key, int round = 32, bool isNetByte = false); 9 v' C+ N' z5 m0 f0 W& _6 l
1.key - 加密或解密用的128-bit(16byte)密钥。 0 Q5 J" c6 `- Q6 d; a$ M
2.round - 加密或解密的轮数,常用的有64,32,16。
. P3 E# K. q, h, z8 e# [8 C9 {3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! ! {# h' s$ r' l( }+ F
; i# ~# f/ x9 m* G3 }& o0 J
最后当然少不了测试代码: |
|