Qt版本的TEA加解密使用

TEA(Tiny Encryption Algorithm) 是一种简单高效的加密算法,以加密解密速度快,实现简单著称。算法真的很简单,TEA算法每一次可以操作64-bit(8-byte),采用128-bit(16-byte)作为key,算法采用迭代的形式,推荐的迭代轮数是64轮,最少32轮。只知道QQ一直用的是16轮TEA。具体关于TEA细节参考google搜索

下面看下Qt下面如何使用

首先新建了一个类util,里面只负责字符串的一些简单转换功能:

#ifndef UTIL_H
#define UTIL_H

#include <QObject>
#include <string>
#include <cmath>
#include <cstdlib>

 using std::string;
class util : public QObject
{
    typedef unsigned char byte;
    typedef unsigned long ulong;
    Q_OBJECT
public:
    explicit util(QObject *parent = 0);
    inline double logbase(double base, double x) {
    return log(x)/log(base);
    }
    /*
    16 *convert int to hex char.
    17 *example:10 -> 'A',15 -> 'F'
    18 */
    char intToHexChar(int x);

     /*
    22 *convert hex char to int.
    23 *example:'A' -> 10,'F' -> 15
    24 */
     int hexCharToInt(char hex);


     /*
    29 *convert a byte array to hex string.
    30 *hex string format example:"AF B0 80 7D"
    31 */
     string bytesToHexString(const byte *in, size_t size);

    /*
    35 *convert a hex string to a byte array.
    36 *hex string format example:"AF B0 80 7D"
    37 */
     size_t hexStringToBytes(const string &str, byte *out);

public slots:

};

#endif // UTIL_H

#include "util.h"
#include <vector>

using namespace std;
util::util(QObject *parent) :
    QObject(parent)
{
}
char util::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 util::hexCharToInt(char hex) {
    hex = toupper(hex);
    if (isdigit(hex))
        return (hex - '0');
    if (isalpha(hex))
        return (hex - 'A' + 10);
    return 0;
}

string util::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 util::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;
}


其次tea类负责对字符串进行加解密工作:

#ifndef TEA_H
#define TEA_H

#include <QObject>
#include <windows.h>
#include <winsock2.h>
#include "util.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;
    }
//    ulong ntoh(ulong netlong);
//    ulong hton(ulong 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
};
#endif // TEA_H

#include "tea.h"
#include <cstring> //for memcpy,memset
#include <cmath>
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 *(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);
}

//ulong Tea::ntoh(ulong netlong)
//{
//    return _isNetByte ? ntohl(netlong) : netlong;
//}

//ulong Tea::hton(ulong hostlong)
//{
//    return _isNetByte ? htonl(hostlong) : hostlong;
//}

下面只是在mian里面对其进行测试功能:

#include "mainwindow.h"
#include <QApplication>
#include "util.h"
#include "tea.h"
#include <string>
#include <QDebug>
#include <iostream>
using namespace std;

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    util m_Util;
    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 = m_Util.hexStringToBytes(plainStr, plain);
    size_t size_key = m_Util.hexStringToBytes(keyStr, key);

    if (size_in != SIZE_IN || size_key != SIZE_KEY)
        return -1;

    std::cout << "Plain: " << m_Util.bytesToHexString(plain, size_in) << endl;
    cout << "Key  : " << m_Util.bytesToHexString(key, size_key) << endl;

    Tea tea(key, 16, true);
    tea.encrypt(plain, crypt);
    cout << "Crypt: " << m_Util.bytesToHexString(crypt, SIZE_OUT) << endl;

    tea.decrypt(crypt, plain);
    cout << "Plain: " << m_Util.bytesToHexString(plain, SIZE_IN) << endl;
    //         return 0;
    return a.exec();
}

这里特别需要注意的是我使用mingw编译器,因为加入了win api,所以需要在pro里面加入
win32:LIBS += -lsetupapi \
                        -lws2_32
只有这样才能编译通过

你可能感兴趣的:(加密,算法,解密,encryption,tea)