|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" * T5 ]9 |7 G: i$ D5 b5 V2 y
2 #include <cstring> //for memcpy,memset
" `' S) o" }6 O& K% a Y$ K 3 & e, m# y# R1 D. R9 w7 u3 u8 H
4 using namespace std; L8 U' E9 v. n
5 $ _5 |( a5 ?( R/ K1 F
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
$ @9 t( v0 M' P% ?0 W; X6 Q1 H 7 :_round(round)
+ j% Z1 w: G, `" j- O$ c- x 8 ,_isNetByte(isNetByte) { $ m; L6 _3 M. K8 X# @ R# a% M5 M
9 if (key != 0) 4 J: I" Z) l: V' O* a3 V
10 memcpy(_key, key, 16); ' F# w5 L# }0 l+ }4 z0 B
11 else ! {2 {; t/ g: j5 t! |
12 memset(_key, 0, 16);
& Q- F- A6 `7 }7 E13 }
; _: F: c* H9 m0 X- |5 q9 j; F% ?14
7 ^! c# _( V, U V5 ?2 G15 TEA::TEA(const TEA &rhs) / b3 N# p/ ]. T m
16 :_round(rhs._round) ~ X7 P* i7 E. [
17 ,_isNetByte(rhs._isNetByte) {
0 J+ G4 I9 Y4 @3 l18 memcpy(_key, rhs._key, 16); % v2 z( N; E2 g* H" U. o
19 }
p3 ]6 L. I2 ?% `- f: {' {( }20
2 {, t, V3 x3 X p2 l21 TEA& TEA::operator=(const TEA &rhs) {
& ~( N) p W; a# ^& e/ D8 L) ~# |3 g22 if (&rhs != this) {
( v! ]# h; P0 J( a23 _round = rhs._round; 6 Q" ?% h" G' W3 G& T
24 _isNetByte = rhs._isNetByte;
+ S8 N6 `9 t4 i; a% D/ a' p& F25 memcpy(_key, rhs._key, 16); ) o- I9 c4 c9 g" P
26 } . ]! M* b* Q+ }- r4 H
27 return *this;
9 |/ g# [. {' a: O v28 }
) R2 G. B- |. u3 E1 z Q29 # G& K* f1 r$ N7 q8 \0 ]
30 void TEA::encrypt(const byte *in, byte *out) {
+ p5 ?4 k! K: {6 c$ M8 J31 encrypt((const ulong*)in, (ulong*)out); 2 A- x5 j `( m. x) r5 x$ l" `9 e9 M: F
32 }
3 F8 {( ?2 k1 Z4 l, N33
1 q p P9 F( m4 h% R34 void TEA::decrypt(const byte *in, byte *out) {
# B# Y/ p4 h/ n2 k9 L! T35 decrypt((const ulong*)in, (ulong*)out); 5 D! v1 t; Q: D4 Y8 m( O* I
36 } + f1 O6 P3 z- v$ W3 o6 `
37 # z, X/ @( ?( w" y. p& g
38 void TEA::encrypt(const ulong *in, ulong *out) {
@4 d0 \7 x/ w: y a7 |1 G- C39 : P q0 ^) r- G5 w% {) r
40 ulong *k = (ulong*)_key;
$ g- n* L) f/ \4 C. r5 X g41 register ulong y = ntoh(in[0]);
* @: o; c, W8 s& L9 \# S42 register ulong z = ntoh(in[1]); & u k N! t6 u2 Z
43 register ulong a = ntoh(k[0]);
1 [/ r1 v; f8 _ x; }44 register ulong b = ntoh(k[1]);
$ O2 Y; H g8 t4 }45 register ulong c = ntoh(k[2]); 7 e% h( g" O9 ?
46 register ulong d = ntoh(k[3]);
8 c; ~$ s( ?- Z. X9 T5 b0 B47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
0 O# p G) Y6 F+ Y0 H& a3 M3 k48 register int round = _round;
: L" G3 o+ ]! E6 z7 C% P49 register ulong sum = 0;
0 A" i1 w& Z, K7 D) K& H50 + ]6 n; a! T* I3 o! I$ K3 u
51 while (round--) { /* basic cycle start */
( c7 k- r) d3 @$ D52 sum += delta; : f" j$ G7 B5 S Y3 V
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); % O0 }9 B$ ^6 N* V9 ?
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); 6 d- v. X. {; i* Z
55 } /* end cycle */
' q' t4 k' N7 D, m7 [56 out[0] = ntoh(y); 0 R% Y2 P6 f) @$ J
57 out[1] = ntoh(z);
- M9 a! J4 C: N5 L58 }
4 t0 P/ n* E: x; E' p59 9 r$ s7 ~' C7 j, o
60 void TEA::decrypt(const ulong *in, ulong *out) {
4 D9 ]6 I. \2 p$ c. Q$ ~61
" m* R9 s' i# f+ ~4 P1 J7 p62 ulong *k = (ulong*)_key;
$ ]* D; ]- N; e! F, O5 o4 ~2 v+ W63 register ulong y = ntoh(in[0]); ) g* d7 W6 I" }
64 register ulong z = ntoh(in[1]);
6 c5 E4 G" o. ^! \+ u65 register ulong a = ntoh(k[0]);
~1 h. V( g5 D6 G66 register ulong b = ntoh(k[1]); 8 M; A. E" G5 H0 K. X: _( D/ }
67 register ulong c = ntoh(k[2]);
4 U3 v6 a, n' ^$ ^* i+ p68 register ulong d = ntoh(k[3]);
2 x y+ W8 a: w5 \4 C3 W# q69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
. \9 ^. Z' K$ H+ {& D# @& h- Q70 register int round = _round; 9 Y" ?1 H: J) I
71 register ulong sum = 0;
; C& z; c1 d( k72 + A! q% a ]- D" C: w
73 if (round == 32) ], l% E0 l0 T# k
74 sum = 0xC6EF3720; /* delta << 5*/ + m/ o' c& S u" M
75 else if (round == 16) " e Q( j, Q$ T, ?7 }! }
76 sum = 0xE3779B90; /* delta << 4*/ 3 D8 Z! ~5 c. H$ C; ?5 h) S
77 else ; |" s5 Z8 e8 H1 }3 A
78 sum = delta << static_cast<int>(logbase(2, round)); : ]+ Z3 ^( L4 b3 I
79
$ s4 f: E _ _80 while (round--) { /* basic cycle start */ , Q, r+ A& r# [$ q
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); 6 J3 t' t7 ?8 J) I6 E4 {
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); " ?4 ^8 f; N# a; ]# O) ]! {
83 sum -= delta;
; O- y' p, F9 ^; W. g84 } /* end cycle */
! _# x" u5 Q2 X2 R3 i2 F4 P3 d! _85 out[0] = ntoh(y); ( O6 L3 ]8 N! z! t' p3 g. g; m
86 out[1] = ntoh(z); . e- o+ C5 V1 N. [; I
87 }
8 h) j- R7 q4 H9 w2 e: _
g0 w/ z* h8 ~% @# W( W, M ], k需要说明的是TEA的构造函数:
; \3 v3 g& U( s$ W ?3 qTEA(const byte *key, int round = 32, bool isNetByte = false);
' M- h. }/ D! N r) T. x, [0 u9 b1.key - 加密或解密用的128-bit(16byte)密钥。
5 a5 U$ ?$ G+ c) o* ~/ ]2.round - 加密或解密的轮数,常用的有64,32,16。 8 R" {" z" E5 P
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! $ R9 J L3 \, E4 A; ^7 b0 O
; ]0 `. b0 \6 k4 v: Z5 F4 Y( B6 h; P
最后当然少不了测试代码: |
|