📄 tea.cpp
字号:
#include <string>
#include <cmath>
#include <cstdlib>
typedef unsigned char byte;
typedef unsigned long ulong;
inline double logbase(double base, double x) {
return log(x)/log(base);
}
/*
*convert int to hex char.
*example:10 -> 'A',15 -> 'F'
*/
char intToHexChar(int x);
/*
*convert hex char to int.
*example:'A' -> 10,'F' -> 15
*/
int hexCharToInt(char hex);
using std::string;
/*
*convert a byte array to hex string.
*hex string format example:"AF B0 80 7D"
*/
string bytesToHexString(const byte *in, size_t size);
/*
*convert a hex string to a byte array.
*hex string format example:"AF B0 80 7D"
*/
size_t hexStringToBytes(const string &str, byte *out);
#include <vector>
using namespace std;
char intToHexChar(int x) {
static const char HEX[16] = {
'0', '1', '2', '3',
'4', '5', '6', '7',
'8', '9', 'A', 'B',
'C', 'D', 'E', 'F'
};
return HEX[x];
}
int hexCharToInt(char hex) {
hex = toupper(hex);
if (isdigit(hex))
return (hex - '0');
if (isalpha(hex))
return (hex - 'A' + 10);
return 0;
}
string bytesToHexString(const byte *in, size_t size) {
string str;
for (size_t i = 0; i < size; ++i) {
int t = in[i];
int a = t / 16;
int b = t % 16;
str.append(1, intToHexChar(a));
str.append(1, intToHexChar(b));
if (i != size - 1)
str.append(1, ' ');
}
return str;
}
size_t hexStringToBytes(const string &str, byte *out) {
vector<string> vec;
string::size_type currPos = 0, prevPos = 0;
while ((currPos = str.find(' ', prevPos)) != string::npos) {
string b(str.substr(prevPos, currPos - prevPos));
vec.push_back(b);
prevPos = currPos + 1;
}
if (prevPos < str.size()) {
string b(str.substr(prevPos));
vec.push_back(b);
}
typedef vector<string>::size_type sz_type;
sz_type size = vec.size();
for (sz_type i = 0; i < size; ++i) {
int a = hexCharToInt(vec[i][0]);
int b = hexCharToInt(vec[i][1]);
out[i] = a * 16 + b;
}
return size;
}
//////////////////////////////////////////////
#include <winsock2.h>
class TEA {
public:
TEA(const byte *key, int round = 32, bool isNetByte = false);
TEA(const TEA &rhs);
TEA& operator=(const TEA &rhs);
void encrypt(const byte *in, byte *out);
void decrypt(const byte *in, byte *out);
private:
void encrypt(const ulong *in, ulong *out);
void decrypt(const ulong *in, ulong *out);
ulong ntoh(ulong netlong) { return _isNetByte ? ntohl(netlong) : netlong; }
ulong hton(ulong hostlong) { return _isNetByte ? htonl(hostlong) : hostlong; }
private:
int _round; //iteration round to encrypt or decrypt
bool _isNetByte; //whether input bytes come from network
byte _key[16]; //encrypt or decrypt key
};
///////////////////////////////////////////////////////////
#include <cstring> //for memcpy,memset
using namespace std;
TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
:_round(round)
,_isNetByte(isNetByte) {
if (key != 0)
memcpy(_key, key, 16);
else
memset(_key, 0, 16);
}
TEA::TEA(const TEA &rhs)
:_round(rhs._round)
,_isNetByte(rhs._isNetByte) {
memcpy(_key, rhs._key, 16);
}
TEA& TEA::operator=(const TEA &rhs) {
if (&rhs != this) {
_round = rhs._round;
_isNetByte = rhs._isNetByte;
memcpy(_key, rhs._key, 16);
}
return *this;
}
void TEA::encrypt(const byte *in, byte *out) {
encrypt((const ulong*)in, (ulong*)out);
}
void TEA::decrypt(const byte *in, byte *out) {
decrypt((const ulong*)in, (ulong*)out);
}
void TEA::encrypt(const ulong *in, ulong *out) {
ulong *k = (ulong*)_key;
register ulong y = ntoh(in[0]);
register ulong z = ntoh(in[1]);
register ulong a = ntoh(k[0]);
register ulong b = ntoh(k[1]);
register ulong c = ntoh(k[2]);
register ulong d = ntoh(k[3]);
register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
register int round = _round;
register ulong sum = 0;
while (round--) { /* basic cycle start */
sum += delta;
y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
} /* end cycle */
out[0] = ntoh(y);
out[1] = ntoh(z);
}
void TEA::decrypt(const ulong *in, ulong *out) {
ulong *k = (ulong*)_key;
register ulong y = ntoh(in[0]);
register ulong z = ntoh(in[1]);
register ulong a = ntoh(k[0]);
register ulong b = ntoh(k[1]);
register ulong c = ntoh(k[2]);
register ulong d = ntoh(k[3]);
register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
register int round = _round;
register ulong sum = 0;
if (round == 32)
sum = 0xC6EF3720; /* delta << 5*/
else if (round == 16)
sum = 0xE3779B90; /* delta << 4*/
else
sum = delta << static_cast<int>(logbase(2, round));
while (round--) { /* basic cycle start */
z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
sum -= delta;
} /* end cycle */
out[0] = ntoh(y);
out[1] = ntoh(z);
}
////////////////
#include <iostream>
using namespace std;
int main() {
const string plainStr("AD DE E2 DB B3 E2 DB B3");
const string keyStr("3A DA 75 21 DB E2 DB B3 11 B4 49 01 A5 C6 EA D4");
const int SIZE_IN = 8, SIZE_OUT = 8, SIZE_KEY = 16;
byte plain[SIZE_IN], crypt[SIZE_OUT], key[SIZE_KEY];
size_t size_in = hexStringToBytes(plainStr, plain);
size_t size_key = hexStringToBytes(keyStr, key);
if (size_in != SIZE_IN || size_key != SIZE_KEY)
return -1;
cout << "Plain: " << bytesToHexString(plain, size_in) << endl;
cout << "Key : " << bytesToHexString(key, size_key) << endl;
TEA tea(key, 16, true);
tea.encrypt(plain, crypt);
cout << "Crypt: " << bytesToHexString(crypt, SIZE_OUT) << endl;
tea.decrypt(crypt, plain);
cout << "Plain: " << bytesToHexString(plain, SIZE_IN) << endl;
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -