|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
: P( a" f/ L6 w. o' P6 j, x9 }0 G 2 #include <cstring> //for memcpy,memset
2 a/ @/ m# }& Y+ r+ ] 3 / y; P8 V4 J' a0 c
4 using namespace std; 8 E F9 F- u) K& L9 q# [: N
5 ) a+ A' Q, K5 T9 R3 l
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) 3 Z5 q( |% x& _7 X% R
7 :_round(round)
* L M5 o0 V& b! O. H% J7 F 8 ,_isNetByte(isNetByte) { 2 Q. X0 q! j% _, B: c5 n- y
9 if (key != 0)
3 {- h, [+ ~2 ^7 f+ z1 z10 memcpy(_key, key, 16); 8 m3 t5 g2 r8 l% U
11 else
5 [; {% J3 J, \$ Y v12 memset(_key, 0, 16);
- P8 K* d, k1 I# J1 O) L# T13 }
% \* Q/ O; j& P' N14
& X6 t1 E! ^7 i15 TEA::TEA(const TEA &rhs)
# q; L+ q- t& N3 W Z16 :_round(rhs._round) # r) e* P2 E. {0 Z4 ^
17 ,_isNetByte(rhs._isNetByte) {
9 S! U: U# X' d: b2 k18 memcpy(_key, rhs._key, 16);
. z0 s1 w% H* V. k' x+ p19 }
9 o2 m+ D- V9 C* f$ l( N, M20 5 J, v6 _6 u1 @* z: K% h3 Y
21 TEA& TEA::operator=(const TEA &rhs) {
. t! ~7 w# I; H22 if (&rhs != this) {
; J5 h4 Q/ l4 a: v23 _round = rhs._round; ! D) D6 Y% \; R7 t3 n Q+ x& j
24 _isNetByte = rhs._isNetByte; ) A' C& w# \* `4 b( R& I/ b
25 memcpy(_key, rhs._key, 16);
* H# @. A7 g; D" Q26 } # E8 \1 A0 v8 l: ~# O" m) {( ]
27 return *this;
' w; ^- {* o6 t* P/ T% J' S/ e7 r% h( E28 }
, M- t" z4 I9 c+ r7 I% Z29 ( m1 }7 u, a0 F/ ?
30 void TEA::encrypt(const byte *in, byte *out) { . O4 M' X9 D- r. b4 W
31 encrypt((const ulong*)in, (ulong*)out);
/ U/ y8 {( I. Y* L7 \- |( \! @5 S7 C32 }
8 O3 F# p* ^0 Q \33
) D) J& j) S/ s& o, H34 void TEA::decrypt(const byte *in, byte *out) { A3 R' V& E ]7 m+ O
35 decrypt((const ulong*)in, (ulong*)out); & H0 m$ q [3 i1 ~4 S, C
36 }
0 j: j3 C; P- q37 " @3 y9 ~! s' u
38 void TEA::encrypt(const ulong *in, ulong *out) {
# \; `5 F L+ k39
" @9 s" R* i$ g2 A40 ulong *k = (ulong*)_key;
- C) x+ C4 S c41 register ulong y = ntoh(in[0]);
4 p% N! _/ U( Y. D5 f- Q. I42 register ulong z = ntoh(in[1]); / t# l6 a6 w2 A2 K3 Q' \
43 register ulong a = ntoh(k[0]);
2 X& U L/ }9 b44 register ulong b = ntoh(k[1]);
% |% w: ~3 e! C2 K1 C) [' N45 register ulong c = ntoh(k[2]);
1 z$ v3 }4 B" J& t9 I. H8 ~46 register ulong d = ntoh(k[3]);
! Y) Z6 Q3 t2 ?8 s" a$ X! [& A. y47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 3 C6 H) x& ^+ A7 n
48 register int round = _round;
0 i; h, o" I+ m! {49 register ulong sum = 0;
+ E* ], x8 K0 G+ Y& P1 p; @% t7 M50
9 c& } Y. I! r- [' i, j51 while (round--) { /* basic cycle start */ : V2 b. z, m# W2 O# d6 z! [0 Y' n
52 sum += delta;
8 V9 i! ]- L3 i% F- n53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
# F4 H) x) C4 h& O7 E8 P54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
' E9 K/ O9 j2 o+ V# ?. w5 e9 r55 } /* end cycle */
( {1 e# a5 x/ j" y5 [0 b' D8 {$ d a56 out[0] = ntoh(y);
( ~- T- \) o6 E57 out[1] = ntoh(z);
, Y: \% X* H& m+ Y, P* s58 } F; [( l( [' x9 F4 z
59
1 k- U* O8 \6 v. n) R. S60 void TEA::decrypt(const ulong *in, ulong *out) { " r5 j% k/ f; |' ?$ y. V, X
61
9 D, v# {9 K n- \8 h62 ulong *k = (ulong*)_key; $ \& U; B, f8 `7 h5 [
63 register ulong y = ntoh(in[0]); ( O: ~9 |* k2 S" r7 T: T
64 register ulong z = ntoh(in[1]); 6 Z* _/ C6 K/ j! _
65 register ulong a = ntoh(k[0]);
# P$ O- ?, t" v/ N" ]: r' G# U: `66 register ulong b = ntoh(k[1]); " E2 J" {; B+ O2 y
67 register ulong c = ntoh(k[2]); 4 r' O, e' G- Y5 u
68 register ulong d = ntoh(k[3]); 2 x# r" |( M* p0 C9 ^
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
6 b% r2 P8 \8 h! X* ^70 register int round = _round;
$ H# H' b1 i0 L/ A$ c/ t3 j71 register ulong sum = 0;
# r& A$ r6 p8 v5 r72
! m6 o/ G" A/ n73 if (round == 32) # H5 @4 m0 t: Y
74 sum = 0xC6EF3720; /* delta << 5*/
: o1 K0 _ a, U* a0 Y75 else if (round == 16) 4 `) @# H3 p d' {) n
76 sum = 0xE3779B90; /* delta << 4*/
. Y4 Z5 c. G; Y- }' `: q77 else
1 s, w {- t* d; e |0 @" D78 sum = delta << static_cast<int>(logbase(2, round)); ( Z# I, [' A7 r$ Y
79 6 D# \" f+ R% C6 k: |0 F L
80 while (round--) { /* basic cycle start */ ; J" b. j. m8 k, j
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); 8 B" i( S: T: G1 V/ s, `
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
& E; r" k7 s" V$ c* M83 sum -= delta; 8 t8 C5 K u b
84 } /* end cycle */ + b5 x( R2 }# X. m
85 out[0] = ntoh(y); : |& j- k5 a! r
86 out[1] = ntoh(z);
0 M# Q% f0 @1 d" f' {87 } y" p6 ?# ?4 H+ \+ d
/ M1 S) ~0 }6 {( {/ Z/ G/ {8 \$ `
需要说明的是TEA的构造函数:
: U) r1 X L0 Z6 s* dTEA(const byte *key, int round = 32, bool isNetByte = false); * G4 r0 l3 j" a+ v# u
1.key - 加密或解密用的128-bit(16byte)密钥。
( a1 N& ?! F$ s) a1 z q2.round - 加密或解密的轮数,常用的有64,32,16。 ; g4 f( g# x4 r0 @! V, F
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
! e( U# ^* |# L+ s# K I [+ P4 F; D6 P* y3 S5 [! t3 T9 ?
最后当然少不了测试代码: |
|