|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h"
! G/ ]/ ~: z9 \% |9 P) A- { 2 #include <cstring> //for memcpy,memset 2 ^7 e- M6 g2 U2 o6 I# }
3 * h3 ~8 {* t/ |# E1 u
4 using namespace std; 8 I2 J% ^$ T& [7 c0 R e; C
5 , p8 Q; H6 J Z9 s
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/) # \+ `- o/ e7 X$ u5 v& l
7 :_round(round)
' ~: d& k; Y! l- `7 i 8 ,_isNetByte(isNetByte) { 4 y. h7 F) V( D" K- W
9 if (key != 0)
; N, m4 O# X- w( W; j10 memcpy(_key, key, 16);
! \! @& I# V+ K0 ^8 S+ F! ?11 else
; P+ ~" Z8 ^9 J12 memset(_key, 0, 16);
, c+ s! u! J& g8 [5 S0 y13 }
& Y( J: ]0 R6 P: N: x3 `14 * M5 M, y7 A; B
15 TEA::TEA(const TEA &rhs)
8 \* }+ g# E2 ~- Z" m16 :_round(rhs._round) 4 E# t1 Z, C* ~# |& e9 C+ g
17 ,_isNetByte(rhs._isNetByte) { 1 a# [& _( F) ]5 C6 u
18 memcpy(_key, rhs._key, 16); : j9 X& g# m" i" X6 H1 ]
19 } 0 O9 [; v+ v/ t8 c
20 + q$ x- a8 u4 ]2 q
21 TEA& TEA::operator=(const TEA &rhs) { 1 C/ n" D' }' Z9 O8 X" B
22 if (&rhs != this) {
9 x+ @" Q6 W! D* O% q23 _round = rhs._round;
& U: u; r, } l& {: J2 ]0 O }24 _isNetByte = rhs._isNetByte;
$ @5 C! j; ~9 g3 {4 B9 [: n9 ]3 y25 memcpy(_key, rhs._key, 16); / n6 _2 q% A1 L# f
26 } 3 Y6 W0 M# H/ M0 F- x, A2 X
27 return *this;
; F7 @& g% [, x/ i28 }
2 o6 k+ g. C) M. v29
6 h. W- v1 x. r, E9 s# k30 void TEA::encrypt(const byte *in, byte *out) { : @, c; _: v% @2 ]+ J- k
31 encrypt((const ulong*)in, (ulong*)out); % Q: h2 a6 M, X! s! j# z
32 } / E4 x# k6 S% j4 A% e. Y5 s
33
$ M1 J: ?0 n) G( f% G* ~1 U% n' J34 void TEA::decrypt(const byte *in, byte *out) {
) I8 S7 U* c7 q; u35 decrypt((const ulong*)in, (ulong*)out); & ]. ~! p: f: \. r0 {( F6 h$ U2 G
36 }
6 t7 p/ }, g) Z( U+ D37
, Y' M, y% _2 i. z) M! r& B! N38 void TEA::encrypt(const ulong *in, ulong *out) {
, m' n! j; L9 z" C% _9 b39
( m* G* e A7 _: w+ t! q40 ulong *k = (ulong*)_key; 3 d8 w4 e7 Y% {+ I) Y, I9 D
41 register ulong y = ntoh(in[0]);
# V; @+ ^$ _2 p2 `9 o( t42 register ulong z = ntoh(in[1]);
, N' p8 O( ]2 m# y1 j$ y43 register ulong a = ntoh(k[0]); 6 S' @- |0 f! t
44 register ulong b = ntoh(k[1]);
7 T9 Y6 b& F6 b9 E% @45 register ulong c = ntoh(k[2]);
5 ^( S( Y3 G& r v46 register ulong d = ntoh(k[3]); $ m9 J( M3 p1 n4 E* m
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */ 7 g7 s. b- w, M1 _
48 register int round = _round;
" V9 A9 k( T$ l9 O49 register ulong sum = 0;
1 R2 ?3 x9 G9 d+ z6 a: T7 L2 N, Q5 ?50
; p/ `* s2 Y J6 |! _8 Q51 while (round--) { /* basic cycle start */ ' ]$ {+ w1 r( {3 D4 I: D/ K" G) G
52 sum += delta; ) t7 {$ B+ w% d' q
53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); # H! i9 b, ?6 D1 ]
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
8 Z8 z+ _7 N ^55 } /* end cycle */
4 S2 G8 o+ S- O/ f1 \1 N56 out[0] = ntoh(y);
4 U* n0 e. Z0 Z0 b, R57 out[1] = ntoh(z);
- A1 S$ T$ O1 Q! }/ Y58 } j4 g3 h+ U* F
59 . @/ N2 T: H7 s1 @1 |( u
60 void TEA::decrypt(const ulong *in, ulong *out) { - z) @8 ~; e8 `8 A1 G6 |6 T4 D
61
( o2 l8 M9 V: q& |8 X3 d. y2 d! Q3 `62 ulong *k = (ulong*)_key; 1 {; E3 o8 f7 L# `0 H
63 register ulong y = ntoh(in[0]); $ D- Z4 C6 v% o- v7 C6 [
64 register ulong z = ntoh(in[1]); 2 g- l+ u. A2 p6 I# w# d
65 register ulong a = ntoh(k[0]); + N) J. R" G) K% q7 D1 R
66 register ulong b = ntoh(k[1]); # C0 k: x2 w. K
67 register ulong c = ntoh(k[2]);
7 \4 k/ C9 |( O! B68 register ulong d = ntoh(k[3]); % O5 A: n( t! T5 @9 ], t+ ?
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
, Z5 f( ?/ Y7 k9 o+ i" F1 O; q70 register int round = _round; ( F. E; \' H9 l+ E% o1 X E
71 register ulong sum = 0;
% ]/ c% s' W1 i$ U# T+ L72
1 D! i5 ?3 m0 M1 A" I! n4 P73 if (round == 32)
, j/ v$ H) N O0 `8 j" i; ~4 W4 A V74 sum = 0xC6EF3720; /* delta << 5*/ 1 Z+ c( b# u* @1 `3 j
75 else if (round == 16)
6 s1 X$ V$ v8 k$ g( u76 sum = 0xE3779B90; /* delta << 4*/ ! ~9 e: f! A$ X7 R+ \# f, Q# E
77 else ; h, p1 N" G5 H% l B) O
78 sum = delta << static_cast<int>(logbase(2, round));
( `3 R/ x D/ e; @" s. D79 6 A0 i5 A n+ B; W( |5 p
80 while (round--) { /* basic cycle start */ # U% X: w, R1 M8 d) Y3 {
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); 8 S5 U/ }8 V) L: w7 L
82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); o" q, R/ I3 ~8 d( B) N# }0 `
83 sum -= delta; . D, G3 i6 P' w K, z# r" U
84 } /* end cycle */ 4 \6 s; ~6 R( ]& `
85 out[0] = ntoh(y); $ b J6 q7 Y8 U4 p, o6 e
86 out[1] = ntoh(z);
; H0 J9 H8 a0 c% y5 e3 v87 }
( B4 }" P5 x# H- ~/ y& j8 O8 G9 @: R* g
需要说明的是TEA的构造函数:
8 f ]/ q5 d, T2 C1 B. v) DTEA(const byte *key, int round = 32, bool isNetByte = false); & n7 f1 G6 C7 n/ |% w
1.key - 加密或解密用的128-bit(16byte)密钥。
: Y( ]9 [ _! ?( ?3 J8 }9 A2.round - 加密或解密的轮数,常用的有64,32,16。
# H: x" v7 H/ ]3 |! K& J3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! ; z2 I6 u+ g5 t2 I. i- W
( e+ [- T( `" E
最后当然少不了测试代码: |
|