|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" 5 n! \" @7 P" }+ V) r3 P5 B
2 #include <cstring> //for memcpy,memset
: I3 l# o; Z/ I# W( J7 A 3
0 U3 ]: t! Y6 @8 T' c 4 using namespace std;
& U+ z8 b& {4 Q' q/ [# C 5
9 y$ }3 E K% d% n' F3 `6 c- M3 h 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) $ [( ^6 M0 \' W8 p! K! {% @
7 :_round(round)
$ P4 h/ d4 O% k" B 8 ,_isNetByte(isNetByte) { 9 T# n" J$ I$ N
9 if (key != 0)
$ w& c2 \: I: \9 ^* K7 [4 }; \10 memcpy(_key, key, 16); ( d- h6 V- B7 s: }& b+ u, f9 D+ d9 Y
11 else
$ F( U' \/ F# u9 K/ i12 memset(_key, 0, 16);
- \0 H6 N% U- P( j, t13 }
$ ]" \. }3 i* z14 / a! r# [2 }2 C* A: }& P
15 TEA::TEA(const TEA &rhs)
5 g5 o0 w. M$ m, w8 v3 n7 B16 :_round(rhs._round)
7 n) u( L/ K4 d5 Z17 ,_isNetByte(rhs._isNetByte) {
! T8 [# |( _4 t+ c7 m6 B6 z18 memcpy(_key, rhs._key, 16); 9 J6 B! E- a9 S$ P) I# ]
19 }
8 {! h1 x, q5 i$ N20 2 H7 o1 P0 w( y T j
21 TEA& TEA::operator=(const TEA &rhs) { 6 O& H- z& X/ a' A+ w
22 if (&rhs != this) {
& t5 b4 Y6 @, y {5 v23 _round = rhs._round;
4 ]2 J4 n& E8 e1 s" M0 V0 x24 _isNetByte = rhs._isNetByte; 8 v3 E+ X9 D( K- t z" _) r1 H
25 memcpy(_key, rhs._key, 16);
5 a, l. c; `7 S4 r- J: v/ c0 J0 F26 }
( ] s: r2 }& O7 i5 d7 Q M1 o$ O: s27 return *this; : ~3 f0 d/ Y8 C" n& l
28 }
' ?+ H. A( w; @! k# z29
7 y: }+ ~" ^- e8 P30 void TEA::encrypt(const byte *in, byte *out) {
# D0 o" q* w. |; P4 ^4 k31 encrypt((const ulong*)in, (ulong*)out); - O4 {: L7 l/ P2 _' a6 e
32 } & C* q: E9 Z' y, ?, E
33
! @8 U& Y/ U, ^, D34 void TEA::decrypt(const byte *in, byte *out) {
, p, y7 L- [& x/ T35 decrypt((const ulong*)in, (ulong*)out); / ?, o5 }0 V8 l' A/ z# t
36 } ; I ]0 x) I4 M6 I$ Y
37 ) V1 R* w5 ^& M$ W" ]
38 void TEA::encrypt(const ulong *in, ulong *out) { 6 z, z$ z$ [# a
39 $ T% S: g$ |+ E2 J1 _
40 ulong *k = (ulong*)_key;
7 j5 O; L3 |$ Z" H41 register ulong y = ntoh(in[0]);
# R1 ~- [! p* f0 [* F9 r42 register ulong z = ntoh(in[1]); ; F. ~) J/ f7 Q; x3 t' b+ U, x
43 register ulong a = ntoh(k[0]); , s2 y( X4 h$ i
44 register ulong b = ntoh(k[1]);
% {( H/ F. r4 W; s W45 register ulong c = ntoh(k[2]);
/ M$ I3 ]/ E) ^9 r4 n( K+ \: _46 register ulong d = ntoh(k[3]);
$ k' X4 E; O1 W$ x) |8 k47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
1 U" x1 `& D M4 S h1 w7 u48 register int round = _round; 2 ?7 r ^* H8 R9 L" [8 F. k2 }
49 register ulong sum = 0;
: t% J8 S* l5 h6 o4 G9 k a) D50 ! L' r) ]$ h* P U1 W
51 while (round--) { /* basic cycle start */
/ y$ X. f8 V7 |& ?$ b o% l2 X0 x5 K7 U52 sum += delta;
: O9 ]. p/ W( j7 G+ }53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); ( _3 R+ `, m1 n$ I1 N; y% H; \! ^
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
0 J4 _3 J6 ~: l) y j55 } /* end cycle */
5 D" [' ]. @0 }' V' s- Z56 out[0] = ntoh(y); 0 f0 d& E9 N. _1 K
57 out[1] = ntoh(z); & _ x5 _+ \$ t
58 } : L+ C; [8 ~+ g; w- e' y" l
59
( ?! J" Y7 {0 r: B0 D60 void TEA::decrypt(const ulong *in, ulong *out) { & o% G* B9 B; y! ]
61
2 E/ o) R: L1 k, {" ^1 k& _3 i62 ulong *k = (ulong*)_key; 7 m! V7 f1 b1 Y2 j# o: E; U1 {
63 register ulong y = ntoh(in[0]); . N% C# [9 i/ M! Z7 m+ [0 l
64 register ulong z = ntoh(in[1]); $ y% R" V+ X/ i/ i `! |
65 register ulong a = ntoh(k[0]); + ?6 ^ x8 O% z) X$ Z$ `( }8 }
66 register ulong b = ntoh(k[1]);
6 Q+ x8 H) k$ B) R. V: i- B67 register ulong c = ntoh(k[2]);
6 w1 T# i6 l9 [68 register ulong d = ntoh(k[3]); 1 ~* S! `/ @, ~
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
( g G* S& t/ ~1 ^70 register int round = _round;
. E2 @2 X: ]% M7 y3 f, N; j71 register ulong sum = 0; & Y( N6 c$ W( O6 V$ ?
72 , {7 O, L2 y/ \% j0 V
73 if (round == 32)
+ C0 q# O- G! z* |& h74 sum = 0xC6EF3720; /* delta << 5*/
8 g# ^, R- A \" }' Y75 else if (round == 16) 0 r$ \4 p, n. n( _
76 sum = 0xE3779B90; /* delta << 4*/ 0 |% Y2 l* W8 }& y' X; v: f+ J
77 else 6 J2 ?+ Y* _7 a, ~% @
78 sum = delta << static_cast<int>(logbase(2, round));
, ?# C$ H* s* J79 ! V, V5 V. x8 h
80 while (round--) { /* basic cycle start */ ) ~' Z( z8 z: W$ U
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
/ M9 l/ {5 K3 O- b82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); , h n! F: O& O; q
83 sum -= delta;
, G) F" ?: B7 D2 ?" C& m7 j6 f3 c84 } /* end cycle */ : u5 N- K0 m6 j6 v, J
85 out[0] = ntoh(y);
2 e. k/ U" J$ U% q$ b( Q86 out[1] = ntoh(z);
w3 x) Q! G) C% {/ q2 G87 }' r( w$ Q- B+ E) w/ Q0 F! Y
4 U' |5 e0 \/ |! C o* p需要说明的是TEA的构造函数:
2 X4 X0 U0 I1 g$ U7 QTEA(const byte *key, int round = 32, bool isNetByte = false); . F U( o; f# X( d/ O9 x& }8 P5 \
1.key - 加密或解密用的128-bit(16byte)密钥。
; ^) {& y* R: {" p5 W; o8 N2.round - 加密或解密的轮数,常用的有64,32,16。
9 X" z+ [3 F, z) B5 Y0 l) F3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
" Q) U. j0 p% r T
# f, m7 S( N, y8 K最后当然少不了测试代码: |
|