|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" - J' n. O( f% Z0 S2 g# n# c
2 #include <cstring> //for memcpy,memset
, M* |+ H+ t/ b& U6 ^ 3 1 e3 r. S+ X6 P1 X
4 using namespace std;
. p- l/ y4 n0 D- _ 5 $ `! l% U, `1 \: o
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) 1 T$ B* u5 D+ O) C- q
7 :_round(round)
7 P/ z$ R5 l- e. |& T3 L8 y 8 ,_isNetByte(isNetByte) {
, X3 F1 g! G3 S, x9 N$ j+ w 9 if (key != 0) 3 U2 s2 i3 M- e- y ~& \
10 memcpy(_key, key, 16);
7 R! t8 m/ t2 F11 else
% ]2 }+ t5 s8 T12 memset(_key, 0, 16);
: o+ F' l e4 Q. {) Z13 }
( P) }- i8 u! M$ U14
2 f' c( R5 v5 m7 d15 TEA::TEA(const TEA &rhs)
( w, }7 w5 z! q3 _16 :_round(rhs._round) . N- G5 o. P H" x4 J/ P: @
17 ,_isNetByte(rhs._isNetByte) {
$ m1 C1 {0 T' D3 W18 memcpy(_key, rhs._key, 16); , h3 S0 J9 S" L$ r1 Z) h
19 }
( z% A: O, \# G* c- |) Y& T/ j20
, E! A! w2 B0 y) p7 X21 TEA& TEA::operator=(const TEA &rhs) {
9 \* e5 z* m- l4 V9 F& j22 if (&rhs != this) { {8 x1 l' N" x9 z
23 _round = rhs._round; 1 f- \: i0 @0 {3 i) D$ ~
24 _isNetByte = rhs._isNetByte;
5 f- T; g! \" J2 ~2 w: W# H$ w) `' q25 memcpy(_key, rhs._key, 16);
5 k( n3 N( a9 g3 N3 U+ j1 [26 } 0 h- Q' `, Y% z
27 return *this; - v8 e- {& g. @9 t
28 }
9 g, A) {! J9 y+ F# F$ Y* z29
+ m* M& ^# G- w* F30 void TEA::encrypt(const byte *in, byte *out) {
8 M7 S6 \, G/ d$ `# l! J( P31 encrypt((const ulong*)in, (ulong*)out); , u6 `9 f( v5 w' n
32 } 4 H6 E! b4 D, o
33
& O% @3 y3 z: \1 H6 Y# N/ o) t- |' L34 void TEA::decrypt(const byte *in, byte *out) { a3 F K' L7 }
35 decrypt((const ulong*)in, (ulong*)out);
4 `' Z1 h! [/ y& R" Q$ B' G36 } 8 y& R2 X0 ^* ]
37 * P2 \0 q V, D, C1 u1 z' C
38 void TEA::encrypt(const ulong *in, ulong *out) { . j) ^- O: Q5 h" L4 ?% p2 L3 ?
39 % S4 U2 b& z# r) v, f3 {
40 ulong *k = (ulong*)_key;
6 g' [( E6 D2 p @5 o) i! B41 register ulong y = ntoh(in[0]);
/ u% A# b* X! ?" r42 register ulong z = ntoh(in[1]); l8 s" a0 j- M5 y
43 register ulong a = ntoh(k[0]);
* U8 n0 ?5 i7 E44 register ulong b = ntoh(k[1]); 5 t6 R; H) ~( E& f7 S' ?: C0 P! P
45 register ulong c = ntoh(k[2]); X) d: {& I( x1 u
46 register ulong d = ntoh(k[3]); : c/ d. a4 ]) C% O. K
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
: z ~4 C, V5 I' A0 U' T48 register int round = _round; % \, _! k+ q5 C4 E
49 register ulong sum = 0; , E* C( u3 y9 o2 R% O9 A
50
& O8 `0 H- f4 X1 P2 Z8 [51 while (round--) { /* basic cycle start */
* L; O( U8 l- ^2 S4 a52 sum += delta;
4 e+ c' K5 O# V/ g# Z53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); . C/ N- m! l; }* ~( q4 @
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
% L# a0 a. W- `9 Z2 K. {55 } /* end cycle */ 6 n1 q0 N a @# f( J/ j+ ?- {
56 out[0] = ntoh(y);
. h1 j5 p9 i$ [57 out[1] = ntoh(z); + }( e3 K: v2 C4 i C
58 }
( `7 R! n3 ^( G$ y3 D59
1 D: v! r: x% c2 K7 L- R. `& {! h60 void TEA::decrypt(const ulong *in, ulong *out) {
3 C5 b, a8 u3 V61
& C Y+ d$ i+ ~. J' S7 z62 ulong *k = (ulong*)_key; 5 L( C$ W9 @/ |: _7 |; Y, D. ?2 D
63 register ulong y = ntoh(in[0]);
& Z0 y2 \$ N$ k- N" O64 register ulong z = ntoh(in[1]); - W( e. F& `( ^# g/ N
65 register ulong a = ntoh(k[0]); - Q2 C. i( y/ Q: N5 D: F6 [
66 register ulong b = ntoh(k[1]);
/ U2 ^" D4 ?" g9 S. H5 ]2 O, U+ U+ h2 m67 register ulong c = ntoh(k[2]); * J" q( ~& l! T/ q2 i- h* [
68 register ulong d = ntoh(k[3]);
' k4 p6 J3 ]- b0 h0 ~4 N3 [6 Q69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ # t4 |: B4 |8 M9 k
70 register int round = _round; 5 N( S# H7 u7 i+ H
71 register ulong sum = 0; . _0 t; ^7 Y; V
72 6 C, g+ Q& _8 M$ G
73 if (round == 32)
4 R, H0 [( O6 n. h5 @& d74 sum = 0xC6EF3720; /* delta << 5*/ 8 Y% o3 P+ Y5 p2 Y5 t
75 else if (round == 16)
+ w& R7 `* T- Y1 J76 sum = 0xE3779B90; /* delta << 4*/ 8 ^$ s2 B1 s$ M2 ~
77 else " p' E, ^6 d% b' f
78 sum = delta << static_cast<int>(logbase(2, round)); - g9 z7 ~/ Y% G% V, e
79
2 r$ D) N" E5 M5 {) F80 while (round--) { /* basic cycle start */ & M ]( t/ G4 F. m: f
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); 1 o8 W( b) o' F+ e. v
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); 5 ]: B7 K* X1 H5 d* ?6 B0 {
83 sum -= delta;
5 h) o1 v1 `: k8 u( y84 } /* end cycle */ C5 W8 s' r& \
85 out[0] = ntoh(y); & O7 A' M) ~( \5 c4 Q
86 out[1] = ntoh(z); # k. }% I2 q, a* E- w. J O' }0 R
87 }) i# I5 @2 r6 ?! ^* k H3 V8 B
2 Z. q. f: ^8 k8 @5 a3 N- ~需要说明的是TEA的构造函数: $ H; T) b0 l# S2 w. i9 T1 E: K
TEA(const byte *key, int round = 32, bool isNetByte = false); 8 x" ]4 v' C y
1.key - 加密或解密用的128-bit(16byte)密钥。 . e! R8 f; m# q
2.round - 加密或解密的轮数,常用的有64,32,16。 ) D% Q1 z: F* \$ O7 S" e) b2 r* e
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!
# s9 A N2 U$ ^
, a4 N! I/ D' V最后当然少不了测试代码: |
|