1. 程式人生 > >TEA加密演算法的C/C++實現

TEA加密演算法的C/C++實現

TEA(Tiny Encryption Algorithm) 是一種簡單高效的加密演算法,以加密解密速度快,實現簡單著稱。演算法真的很簡單,TEA演算法每一次可以操作64-bit(8-byte),採用128-bit(16-byte)作為key,演算法採用迭代的形式,推薦的迭代輪數是64輪,最少32輪。目前我只知道QQ一直用的是16輪TEA。沒什麼好說的,先給出C語言的原始碼(預設是32輪):
 1 void encrypt(unsigned long*v, unsigned long*k) {
 2     unsigned long y=v[0], z=v[1], sum=0, i;         
/* set up */
 3     unsigned long delta=0x9e3779b9;                 /* a key schedule constant */ 4     unsigned long a=k[0], b=k[1], c=k[2], d=k[3];   /* cache key */ 5 for (i=0; i <32; i++) {                        /* basic cycle start */ 6         sum += delta;
 7         y += ((z<<4+ a) ^ (z + sum) 
^ ((z>>5+
 b);
 8         z += ((y<<4+ c) ^ (y + sum) ^ ((y>>5+ d);/* end cycle */
 9     }
10     v[0]=
y;
11     v[1]=
z;
12 
}
13 
14 void decrypt(unsigned long*v, unsigned long*k) {
15     unsigned long y=v[0], z=v[1], sum=0xC6EF3720, i; /* set up */
16     unsigned long delta=0x9e3779b9;                  
/* a key schedule constant */
17     unsigned long a=k[0], b=k[1], c=k[2], d=k[3];    /* cache key */18 for(i=0; i<32; i++) {                            /* basic cycle start */19         z -= ((y<<4+ c) ^ (y + sum) ^ ((y>>5+ d);
20         y -= ((z<<4+ a) ^ (z + sum) ^ ((z>>5+
 b);
21         sum -= delta;                                /* end cycle */
22     }
23     v[0]=
y;
24     v[1]=
z;
25 }

C語言寫的用起來當然不方便,沒關係,用C++封裝以下就OK了:
util.h
 1 #ifndef UTIL_H
 2 
#define UTIL_H
 3 
 4 #include <string> 5 #include <cstdlib> 6  7 typedef unsigned charbyte;
 8 typedef unsigned long
 ulong;
 9 
10 /*11 *convert int to hex char.
12 
*example:10 -> 'A',15 -> 'F'
13 */
14 char intToHexChar(int x);
15 
16 /*17 *convert hex char to int.
18 
*example:'A' -> 10,'F' -> 15
19 */
20 int hexCharToInt(char hex);
21 
22 using std::string;
23 /*
24 *convert a byte array to hex string.
25 
*hex string format example:"AF B0 80 7D"
26 */
27 string bytesToHexString(constbyte*in, size_t size);
28 
29 /*30 *convert a hex string to a byte array.
31 
*hex string format example:"AF B0 80 7D"
32 */
33 size_t hexStringToBytes(const string &str, byte*out);
34 
35 #endif/*UTIL_H*/
util.cpp
 1 #include "util.h" 2 #include <vector> 3  4 using namespace std;
 5 
 6 char intToHexChar(int x) {
 7 staticconstchar HEX[16=
 {
 8 '0''1''2''3'
,
 9 '4''5''6''7'
,
10 '8''9''A''B'
,
11 'C''D''E''F'
12     };
13 return
 HEX[x];
14 
}
15 
16 int hexCharToInt(char hex) {
17     hex =
 toupper(hex);
18 if
 (isdigit(hex))
19 return (hex -'0'
);
20 if
 (isalpha(hex))
21 return (hex -'A'+10
);
22 return0
;
23 
}
24 
25 string bytesToHexString(constbyte*in, size_t size) {
26 
    string str;
27 for (size_t i =0; i < size; ++
i) {
28 int t =
 in[i];
29 int a = t /16
;
30 int b = t %16
;
31         str.append(1
, intToHexChar(a));
32         str.append(1
, intToHexChar(b));
33 if (i != size -1
)
34             str.append(1''
);
35 
    }
36 return
 str;
37 
}
38 
39 size_t hexStringToBytes(const string &str, byte*out) {
40 
41     vector<string> vec;
42     string::size_type currPos =0, prevPos =0
;
43 while ((currPos = str.find('', prevPos)) !=
 string::npos) {
44         string b(str.substr(prevPos, currPos -
 prevPos));
45 
        vec.push_back(b);
46         prevPos = currPos +1
;
47 
    }
48 if (prevPos <
 str.size()) {
49 
        string b(str.substr(prevPos));
50 
        vec.push_back(b);
51 
    }
52     typedef vector<string>
::size_type sz_type;
53     sz_type size =
 vec.size();
54 for (sz_type i =0; i < size; ++
i) {
55 int a = hexCharToInt(vec[i][0
]);
56 int b = hexCharToInt(vec[i][1
]);
57         out[i] = a *16+
 b;
58 
    }
59 return
 size;
60 }

tea.h
 1 #ifndef TEA_H
 2 
#define TEA_H
 3 
 4 /* 5 *for htonl,htonl
 6 
*do remember link "ws2_32.lib"
 7 */
 8 #include <winsock2.h> 9 #include "util.h"10 11 class TEA {
12 public
:
13     TEA(constbyte*key, int round =32, bool isNetByte =false
);
14     TEA(const TEA &
rhs);
15     TEA& operator=(const TEA &
rhs);
16 void encrypt(constbyte*in, byte*
out);
17 void decrypt(constbyte*in, byte*
out);
18 private
:
19 void encrypt(const ulong *in, ulong *
out);
20 void decrypt(const ulong *in, ulong *
out);
21     ulong ntoh(ulong netlong) { return _isNetByte ?
 ntohl(netlong) : netlong; }
22     ulong hton(ulong hostlong) { return _isNetByte ?
 htonl(hostlong) : hostlong; }
23 private
:
24 int _round; //iteration round to encrypt or decrypt
25     bool _isNetByte; //whether input bytes come from network26 byte _key[16]; //encrypt or decrypt key27 };
28 
29 #endif/*TEA_H*/
tea.cpp
 1 #include "tea.h" 2 #include <cstring>//for memcpy,memset 3  4 using namespace std;
 5 
 6 TEA::TEA(constbyte*key, int round /*= 32*/, bool isNetByte /*= false*/)
 7 
:_round(round)
 8 
,_isNetByte(isNetByte) {
 9 if (key !=0
)
10         memcpy(_key, key, 16
);
11 else
12         memset(_key, 016);
13 
}
14 
15 TEA::TEA(const TEA &rhs)
16 
:_round(rhs._round)
17 
,_isNetByte(rhs._isNetByte) {
18     memcpy(_key, rhs._key, 16
);
19 
}
20 
21 TEA& TEA::operator=(const TEA &rhs) {
22 if (&rhs !=this
) {
23         _round =
 rhs._round;
24         _isNetByte =
 rhs._isNetByte;
25         memcpy(_key, rhs._key, 16
);
26 
    }
27 return*this
;
28 
}
29 
30 void TEA::encrypt(constbyte*in, byte*out) {
31     encrypt((const ulong*)in, (ulong*
)out);
32 
}
33 
34 void TEA::decrypt(constbyte*in, byte*out) {
35     decrypt((const ulong*)in, (ulong*
)out);
36 
}
37 
38 void TEA::encrypt(const ulong *in, ulong *out) {
39 
40     ulong *= (ulong*)_key;
41     register ulong y = ntoh(in[0
]);
42     register ulong z = ntoh(in[1
]);
43     register ulong a = ntoh(k[0
]);
44     register ulong b = ntoh(k[1
]);
45     register ulong c = ntoh(k[2
]);
46     register ulong d = ntoh(k[3
]);
47     register ulong delta =0x9E3779B9/* (sqrt(5)-1)/2*2^32 */
48     register int round = _round;
49     register ulong sum =0
;
50 
51 while (round--) {    /* basic cycle start */52         sum += delta;
53         y += ((z <<4+ a) ^ (z + sum) ^ ((z >>5+
 b);
54         z += ((y <<4+ c) ^ (y + sum) ^ ((y >>5+
 d);
55     }    /* end cycle */
56     out[0= ntoh(y);
57     out[1=
 ntoh(z);
58 
}
59 
60 void TEA::decrypt(const ulong *in, ulong *out) {
61 
62     ulong *= (ulong*)_key;
63     register ulong y = ntoh(in[0
]);
64     register ulong z = ntoh(in[1
]);
65     register ulong a = ntoh(k[0
]);
66     register ulong b = ntoh(k[1
]);
67     register ulong c = ntoh(k[2
]);
68     register ulong d = ntoh(k[3
]);
69     register ulong delta =0x9E3779B9/* (sqrt(5)-1)/2*2^32 */
70     register int round = _round;
71     register ulong sum =0
;
72 
73 if (round ==32)
74         sum =0xC6EF3720/* delta << 5*/
75 elseif (round ==16)
76         sum =0xE3779B90/* delta << 4*/
77 else78         sum = delta * round;
79 
80 while (round--) {    /* basic cycle start */81         z -= ((y <<4+ c) ^ (y + sum) ^ ((y >>5+ d);
82         y -= ((z <<4+ a) ^ (z + sum) ^ ((z >>5+
 b);
83         sum -=
 delta;
84     }    /* end cycle */
85     out[0