|
|
发表于 2010-1-19 19:59:57
|
显示全部楼层
tea.cpp
1 #include "tea.h" ) U+ S5 [) ?' n: A# E+ t8 v
2 #include <cstring> //for memcpy,memset + n$ f: K3 w- F1 d% Y
3 - U; o# c9 v/ N+ u
4 using namespace std;
, t8 o! J& ?% l" o 5 + p- Y K1 h6 Z" g/ i1 p
6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
0 R" J7 ^/ G/ U 7 :_round(round) : ^/ u9 l9 _) X* I( q
8 ,_isNetByte(isNetByte) {
% B$ F, [. G0 i( ~8 n8 T 9 if (key != 0)
: i' [; A7 V1 Q7 C1 P' s10 memcpy(_key, key, 16);
! |( n. ]5 o4 S1 f8 k3 X; G' }9 j: K11 else + c1 j0 [( ~# s7 E4 b# |
12 memset(_key, 0, 16);
# ]0 n& V8 G, U. B7 l, E2 R13 }
" y' M$ k U x$ r& o14 6 u2 ^% ?! w% [( e& w0 z! X# s c
15 TEA::TEA(const TEA &rhs)
% W' k5 U5 T1 v7 p+ n Q3 R) a16 :_round(rhs._round) - ~4 D+ s& m( N4 _
17 ,_isNetByte(rhs._isNetByte) { 7 B8 ]9 P9 }$ T
18 memcpy(_key, rhs._key, 16); # B( i& d- A k% G! E0 d, \" Z
19 } 5 M' B0 U# C; V, e- q
20
) q9 L# A' ^% ]" N21 TEA& TEA::operator=(const TEA &rhs) { 9 P! f% y! A$ `% [
22 if (&rhs != this) { 9 a% b6 o1 ]9 B5 {
23 _round = rhs._round; 7 R3 J5 |0 T3 i6 U" ~+ q( i
24 _isNetByte = rhs._isNetByte;
# C& }+ G4 Z) t: d, t5 G* n3 p; g* V- S25 memcpy(_key, rhs._key, 16);
) G# u! K4 R( i5 w26 } 3 K3 j" V. G H9 U, I& s% g* V
27 return *this;
0 g) ^0 M0 |$ u4 ^: _5 g; c" Q28 }
8 n4 l' v+ d5 A0 w# K0 A3 t( O29 2 L! P2 O# r3 s4 i; z
30 void TEA::encrypt(const byte *in, byte *out) { 5 ~8 o. c* @! v( d/ g
31 encrypt((const ulong*)in, (ulong*)out); ; v: n7 x8 e3 B
32 }
! l4 l( J( d/ x( \33 : @- k9 H/ K A5 F# q2 c
34 void TEA::decrypt(const byte *in, byte *out) { 1 c! N: ^$ ?# G( f. V' I$ ~
35 decrypt((const ulong*)in, (ulong*)out);
+ `! |7 U, {2 ?* Y( n; `$ @36 } 6 A7 ^' i# e9 z$ ]$ ^! r8 ^
37 : G* Z- z X) L4 S. o- R' n
38 void TEA::encrypt(const ulong *in, ulong *out) {
0 p/ J- x9 w' d! D2 Q39 5 X* M# D. Z8 c" k- ?. M: V
40 ulong *k = (ulong*)_key;
. `( e4 w% M4 m6 a9 A, N41 register ulong y = ntoh(in[0]);
+ j! z9 q5 }2 Y& P- e" E. x42 register ulong z = ntoh(in[1]); 3 |4 L i# {, R- K0 p5 Q
43 register ulong a = ntoh(k[0]);
; c/ c D! ~! B, [ \7 Y( X44 register ulong b = ntoh(k[1]);
8 G) [" }/ {& d% b& `45 register ulong c = ntoh(k[2]); & ? n' i0 v8 T; o3 o$ J7 z
46 register ulong d = ntoh(k[3]); / d8 \6 `4 X7 K( t, X# m: k% B* ~3 c
47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
9 l: v B D3 S48 register int round = _round; . L% ~" e) U' ]# F0 {. Y
49 register ulong sum = 0;
! w% Q6 R" y* C5 r50
* g" q. ~+ F5 u51 while (round--) { /* basic cycle start */ , _4 J# d( f$ |: k
52 sum += delta;
G7 {8 V) T! q$ n$ a+ c53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); ?% F( Z. z' G% p6 F! t
54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); # D4 }" |6 T" z* P
55 } /* end cycle */
4 p9 A; S3 h% S' U7 {2 f0 |56 out[0] = ntoh(y); * [; w9 P- A7 t" K+ `7 Q- [
57 out[1] = ntoh(z);
: [7 a9 A% G7 [5 \58 } 5 {, r+ S( j. w7 Q9 o# `' G
59 ( A( p5 m2 U; s. f
60 void TEA::decrypt(const ulong *in, ulong *out) {
3 P7 ?: V9 p- Y2 {5 |61
- T: d2 R5 ]7 |8 b62 ulong *k = (ulong*)_key; $ ?0 p* B) j+ k! O
63 register ulong y = ntoh(in[0]);
: D" \( Z: }8 N64 register ulong z = ntoh(in[1]); 6 \) k( @1 ]# p X" S& {
65 register ulong a = ntoh(k[0]);
. L) w- U' s4 F4 Y66 register ulong b = ntoh(k[1]); , x- f- H& G7 N5 H8 D& X* r# j0 V
67 register ulong c = ntoh(k[2]);
1 ^# W: N. q' U( z& k68 register ulong d = ntoh(k[3]); 7 o, e6 z3 ?! L& Y4 z6 F/ g
69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
# S- p1 e+ ~+ b {9 Q; Y% d70 register int round = _round; 4 |9 x& X: v1 O2 M% F/ h
71 register ulong sum = 0;
4 `; d5 u- X7 V. }72 & }/ z: m! h7 e- U# s
73 if (round == 32)
" b, W: ]4 g e5 k9 d' C74 sum = 0xC6EF3720; /* delta << 5*/
' l# Q) N7 `9 Z2 D75 else if (round == 16)
- U) { W" Y& w76 sum = 0xE3779B90; /* delta << 4*/ * w% f( `. W7 O
77 else
4 \2 P: L( \9 K# R6 F4 F9 g; O* r78 sum = delta << static_cast<int>(logbase(2, round));
$ i0 \8 Y6 p1 b: T W) t( |7 x79 + _' Q# [. e# a4 I
80 while (round--) { /* basic cycle start */ " e! B" _& @# ]0 B4 v7 @4 o1 V( T
81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
4 l4 Q$ b7 U5 x8 F* R/ l4 T82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
; I( o( M, a$ b s2 I* ? ~83 sum -= delta;
/ N6 I0 y. q* x8 K$ v84 } /* end cycle */
# r3 X7 D' x! Z7 {# [3 D! _85 out[0] = ntoh(y); 2 q" w3 P0 T$ @5 D0 s- k
86 out[1] = ntoh(z); 5 D7 Z9 |/ O8 n/ y+ {7 Z
87 }
B' l3 B2 Y! c) L6 e
# i8 ], B0 M. [5 x+ J8 C9 ]% p需要说明的是TEA的构造函数: W1 P1 r9 g+ T0 k9 q4 r5 X
TEA(const byte *key, int round = 32, bool isNetByte = false); u6 k# h7 u" E4 D0 N0 `
1.key - 加密或解密用的128-bit(16byte)密钥。
Y' \4 ?6 C- q$ E9 q& X5 a2.round - 加密或解密的轮数,常用的有64,32,16。
' G8 {6 [* e' J, l" A+ R* Y3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的! / a$ b( o/ B+ _ Q8 d' a. [
# e; k7 w4 \ T& @* A最后当然少不了测试代码: |
|