#include "des3encryption.h"
#include <openssl/des.h>
Des3Encryption::Des3Encryption()
{

}

QByteArray Des3Encryption::pkcs7Padding(const QByteArray& data, int blockSize) {
    int padding = blockSize - (data.size() % blockSize);
    QByteArray paddedData = data;
    paddedData.append(QByteArray(padding, static_cast<char>(padding)));
    return paddedData;
}

// PKCS#7 去填充函数
QByteArray Des3Encryption::pkcs7Unpadding(const QByteArray& data) {
    if (data.isEmpty()) {
        return data;
    }
    int padding = static_cast<unsigned char>(data[data.size() - 1]);
    if (padding > data.size()) {
        return data;
    }
    return data.left(data.size() - padding);
}

// DES 加密函数
QByteArray Des3Encryption::desEncrypt(const QByteArray& data, const QByteArray& key) {
    DES_cblock desKey;
    memcpy(desKey, key.constData(), 8);
    DES_key_schedule schedule;
    DES_set_key(&desKey, &schedule);

    QByteArray encryptedData;
    for (int i = 0; i < data.size(); i += 8) {
        DES_cblock inputBlock;
        memcpy(inputBlock, data.constData() + i, 8);
        DES_cblock outputBlock;
        DES_ecb_encrypt(&inputBlock, &outputBlock, &schedule, DES_ENCRYPT);
        encryptedData.append(reinterpret_cast<const char*>(outputBlock), 8);
    }
    return encryptedData;
}

// DES 解密函数
QByteArray Des3Encryption::desDecrypt(const QByteArray& data, const QByteArray& key) {
    DES_cblock desKey;
    memcpy(desKey, key.constData(), 8);
    DES_key_schedule schedule;
    DES_set_key(&desKey, &schedule);

    QByteArray decryptedData;
    for (int i = 0; i < data.size(); i += 8) {
        DES_cblock inputBlock;
        memcpy(inputBlock, data.constData() + i, 8);
        DES_cblock outputBlock;
        DES_ecb_encrypt(&inputBlock, &outputBlock, &schedule, DES_DECRYPT);
        decryptedData.append(reinterpret_cast<const char*>(outputBlock), 8);
    }
    return decryptedData;
}

// 3DES 加密函数
QByteArray Des3Encryption::des3Encrypt(const QByteArray& data, const QByteArray& key) {
    // 将密钥填充到 24 字节
    QByteArray paddedKey = key.leftJustified(24, '\0');
    // 对数据进行 PKCS#7 填充
    QByteArray paddedData = pkcs7Padding(data, 8);
    QByteArray k1 = paddedKey.mid(0, 8);
    QByteArray k2 = paddedKey.mid(8, 8);
    QByteArray k3 = paddedKey.mid(16, 8);
    QByteArray temp1 = desEncrypt(paddedData, k1);
    QByteArray temp2 = desDecrypt(temp1, k2);
    QByteArray encrypted = desEncrypt(temp2, k3);

    return encrypted;
}

// 3DES 解密函数
QByteArray Des3Encryption::des3Decrypt(const QByteArray& data, const QByteArray& key) {
    // 将密钥填充到 24 字节
    QByteArray paddedKey = key.leftJustified(24, '\0');
    QByteArray k1 = paddedKey.mid(0, 8);
    QByteArray k2 = paddedKey.mid(8, 8);
    QByteArray k3 = paddedKey.mid(16, 8);
    QByteArray temp1 = desDecrypt(data, k3);
    QByteArray temp2 = desEncrypt(temp1, k2);
    QByteArray decrypted = desDecrypt(temp2, k1);
    return pkcs7Unpadding(decrypted);
}
