|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" ) U% U, T4 w9 Z/ l# T4 {5 B
2 #include <cstring> //for memcpy,memset . U* w( N: L( Z( z
3 , q4 H, E9 f. i! E2 v x
4 using namespace std; : ?8 ]' v" D" D& X) n0 G) A
5 / W2 K7 d5 I, v% `3 n
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) 2 K; n' F8 v# X7 ?9 }
7 :_round(round)
9 R( Q$ {' I W9 P' `4 B 8 ,_isNetByte(isNetByte) { & h. G) t" M; s4 X4 @" H0 z3 q& D
9 if (key != 0) & }5 D- L7 {6 h$ T s& H4 F
10 memcpy(_key, key, 16);
- F3 h, M- N/ T- F11 else
0 b8 n# {8 j! l* p' s) n+ M. q12 memset(_key, 0, 16);
* ?; E- U6 n; H0 F; {13 }
" ~, ^6 @; N7 Q( _14
; z h O P# B1 Y8 g* @# X. k0 I15 TEA::TEA(const TEA &rhs) 1 S& r: [: w+ m5 F
16 :_round(rhs._round) $ U! g" A! w5 H+ ~ z7 |
17 ,_isNetByte(rhs._isNetByte) {
" w p% A: l6 I8 X18 memcpy(_key, rhs._key, 16);
7 Y7 P$ z# t; C% p3 ~; F0 W0 ?% S19 }
, H: M4 p# @* g# q( p20 1 a% Y0 o W0 S
21 TEA& TEA::operator=(const TEA &rhs) { . E. F6 q Q: s' ?, O$ N) B
22 if (&rhs != this) { & G: S i. L; ^( ~
23 _round = rhs._round;
# e. {+ R; f% V$ g# @! h24 _isNetByte = rhs._isNetByte;
$ R+ E5 c7 M5 W# p1 r7 O' D) ~25 memcpy(_key, rhs._key, 16); 3 T. n0 }4 l ?7 K3 V
26 } 5 J1 ^3 I3 u2 O) t, S* k1 `1 S E
27 return *this;
2 }2 h& i; K- t) [8 t' b! O3 s4 j28 } * y: j/ {$ Z! u9 k1 ]) m
29
* _% ]& I2 t8 X7 f1 i0 r30 void TEA::encrypt(const byte *in, byte *out) {
: z. a1 d4 x8 N- }31 encrypt((const ulong*)in, (ulong*)out); * g. k* {8 p* y" O$ Y
32 } & ^, F2 H0 x$ N( K$ x
33 % T. X5 X0 [: y$ T8 p$ d. o
34 void TEA::decrypt(const byte *in, byte *out) {
; c; e1 K+ G4 Q3 q, k7 X35 decrypt((const ulong*)in, (ulong*)out);
8 Y/ L7 T! _7 s5 f1 Y36 }
! @1 Y, m% R" |2 \5 w* P1 L$ J37 ; l" w8 n4 |6 Z
38 void TEA::encrypt(const ulong *in, ulong *out) {
8 B( b' @* Y, }0 `39
( _8 x# ]) O% O% c3 }7 s- k$ h40 ulong *k = (ulong*)_key; 1 k) k/ _% s5 g9 q! Q+ o
41 register ulong y = ntoh(in[0]); 5 a7 _% E1 U& I- d
42 register ulong z = ntoh(in[1]); + B9 d1 f: j/ s
43 register ulong a = ntoh(k[0]); 9 ]. m" N# H1 U: z& \
44 register ulong b = ntoh(k[1]); - @- N/ L: h3 L9 e0 i% M
45 register ulong c = ntoh(k[2]); 5 A( w. ?1 ^5 o5 p
46 register ulong d = ntoh(k[3]);
% T% S. S( h& f' Q+ }" C' m m47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 7 [ ?, N3 `' \: v! e
48 register int round = _round;
H; c, s9 Z# P. W' C49 register ulong sum = 0;
7 F. B6 A# K: y50
8 v& T. ?& n y% b7 m$ A, ?51 while (round--) { /* basic cycle start */ : J! d, @+ {0 D, a2 s
52 sum += delta;
1 N6 i# M. N; Y1 |: V53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
: j/ V) L Y. b0 _# `& q0 S54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); ! z9 I: y6 y6 b+ S# s" D
55 } /* end cycle */
& s7 Y, X g1 P; x& y! X9 ?56 out[0] = ntoh(y); & K8 o T! z h C! K; e. v; ~
57 out[1] = ntoh(z);
V8 |, [ I; I, L8 }58 } ! i$ F1 _; v) Q0 F$ o! e; n
59 5 Y1 E# X! R i5 ]$ r5 e) |
60 void TEA::decrypt(const ulong *in, ulong *out) {
Z, k; c! C0 a# q& L61 % I( y5 b# }5 G" v3 @
62 ulong *k = (ulong*)_key; & A4 N' v5 }+ I
63 register ulong y = ntoh(in[0]);
& \/ [; p9 S& A- W' X* \. Z64 register ulong z = ntoh(in[1]);
+ F+ s$ U* v- D6 _1 s m" p' n5 K% a65 register ulong a = ntoh(k[0]); & y, e+ v7 k: c. X; Z; D3 Z6 d1 [* M. _
66 register ulong b = ntoh(k[1]);
! m6 o: x1 ]$ y- b& o5 P67 register ulong c = ntoh(k[2]); 2 X9 y! L; R2 J+ h* D2 x! c6 ^( P( u
68 register ulong d = ntoh(k[3]);
; @) _* q8 {/ t) }% B8 d69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ , v) T- q8 Q- @* U
70 register int round = _round; 1 e. E0 n4 w9 p$ J8 A/ O) c9 {8 O
71 register ulong sum = 0;
) g* S$ o: R" q72
) Q+ F+ D8 T9 w+ H73 if (round == 32)
( z3 A" b' f) b4 z74 sum = 0xC6EF3720; /* delta << 5*/
/ s" x# g' h1 z; d6 U+ o75 else if (round == 16) 6 C/ _ R! @% u2 U- t
76 sum = 0xE3779B90; /* delta << 4*/
1 W& \6 p, G5 I) h9 ~5 ?4 |77 else 8 j3 R2 P# Y& @7 Y
78 sum = delta << static_cast<int>(logbase(2, round));
( |5 p. x5 E/ V79 * r. W# g4 t) m8 P: Y$ R$ B
80 while (round--) { /* basic cycle start */
1 X# D) k& N9 r: S% g- a8 J81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); ! K% S4 ]( y& j& \. F% [0 ?2 v/ x
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); + G9 Q, e6 B) Y9 V w: {
83 sum -= delta;
, y! ^+ s+ ?4 G84 } /* end cycle */ ; x" ~/ s9 z6 {. w' X4 c
85 out[0] = ntoh(y); 1 z7 a! z: F- b5 ~
86 out[1] = ntoh(z);
4 R( u! N! F" }3 n87 }) ~7 k! H9 V; N7 H& i. D
& y8 v0 I- g, v9 ~! J需要说明的是TEA的构造函数:
- Y( `% @, D# i! F8 }6 f$ C2 HTEA(const byte *key, int round = 32, bool isNetByte = false); 0 v+ Z# O4 R6 C& Y% |1 z
1.key - 加密或解密用的128-bit(16byte)密钥。 - E+ z9 P6 Y( Z' g2 r4 V
2.round - 加密或解密的轮数,常用的有64,32,16。
. E/ I3 M- y( J, w& S3 a R* p2 J3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! 0 X1 c' Q3 C8 O8 n& j: @8 l4 @* f
- p7 g/ L( `9 y6 Y/ z( d2 R- ^( D+ V最后当然少不了测试代码: |
|