From 2830cce39c0f3e677993bb19c031eb61b43659a3 Mon Sep 17 00:00:00 2001
From: ccy <3140717620@qq.com>
Date: 星期四, 21 五月 2026 10:25:23 +0800
Subject: [PATCH] 同步与CNNCSIM的加密解密的方式

---
 licensedata.h            |   57 ++
 tinyaes.cpp              |  264 ++++++++++++
 mainwindow.h             |   18 
 tinyaes.h                |   21 
 mainwindow.cpp           |  281 +++++++----
 shortcrypto.cpp          |  200 +++++++++
 LicenseAdministrator.pro |   10 
 aesni-key-exp.h          |    9 
 shortcrypto.h            |   40 +
 mainwindow.ui            |  254 +++++-----
 licensedata.cpp          |  166 +++++++
 11 files changed, 1,078 insertions(+), 242 deletions(-)

diff --git a/LicenseAdministrator.pro b/LicenseAdministrator.pro
index ada371e..82907aa 100644
--- a/LicenseAdministrator.pro
+++ b/LicenseAdministrator.pro
@@ -16,17 +16,23 @@
 #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
 
 SOURCES += \
+    licensedata.cpp \
     main.cpp \
     mainwindow.cpp \
-    qaesencryption.cpp
+    qaesencryption.cpp \
+    shortcrypto.cpp \
+    tinyaes.cpp
 
 HEADERS += \
     aesni-enc-cbc.h \
     aesni-enc-ecb.h \
     aesni-key-exp.h \
     aesni-key-init.h \
+    licensedata.h \
     mainwindow.h \
-    qaesencryption.h
+    qaesencryption.h \
+    shortcrypto.h \
+    tinyaes.h
 
 FORMS += \
     mainwindow.ui
diff --git a/aesni-key-exp.h b/aesni-key-exp.h
index 4816cca..35c6bfa 100644
--- a/aesni-key-exp.h
+++ b/aesni-key-exp.h
@@ -10,9 +10,12 @@
 
 bool check_aesni_support()
 {
-    unsigned int a,b,c,d;
-    cpuid(1, a,b,c,d);
-    return (c & 0x2000000);
+//    unsigned int a,b,c,d;
+//    cpuid(1, a,b,c,d);
+//    return (c & 0x2000000);
+    // 强制禁用 AES-NI,使用纯软件 AES 实现
+    // 在 MSVC2017 + Qt 5.12.7 环境下,AES-NI 路径存在兼容性问题
+    return false;
 }
 
 __m128i AES_128_ASSIST (__m128i temp1, __m128i temp2)
diff --git a/licensedata.cpp b/licensedata.cpp
new file mode 100644
index 0000000..26d5d1b
--- /dev/null
+++ b/licensedata.cpp
@@ -0,0 +1,166 @@
+锘�#include "licensedata.h"
+#include <QDataStream>
+#include <QtDebug>
+
+LicenseData::LicenseData()
+    : productId(0), verMajor(0), verMinor(0), activeState(0)
+{
+}
+
+QByteArray LicenseData::toBinary() const
+{
+    QByteArray data;
+    data.reserve(64);
+    QDataStream stream(&data, QIODevice::WriteOnly);
+    stream.setByteOrder(QDataStream::BigEndian);
+
+    // 1. 涓绘澘UUID锛氬浐瀹�16瀛楄妭
+    QByteArray uuid = boardUuid.left(16);
+    uuid.append(QByteArray(16 - uuid.size(), '\0'));
+    stream.writeRawData(uuid.constData(), 16);
+
+    // 2. CPU搴忓垪鍙凤細鍥哄畾8瀛楄妭
+    QByteArray cpu = cpuSerial.left(8);
+    cpu.append(QByteArray(8 - cpu.size(), '\0'));
+    stream.writeRawData(cpu.constData(), 8);
+
+    // 3. 鐢ㄦ埛鍚嶏細闀垮害鍓嶇紑(1B) + UTF-8鏁版嵁
+    QByteArray userBytes = userName.toUtf8();
+    if (userBytes.size() > 255) {
+        userBytes = userBytes.left(255);
+    }
+    stream << static_cast<quint8>(userBytes.size());
+    stream.writeRawData(userBytes.constData(), userBytes.size());
+
+    // 4. 澶辨晥鏃ユ湡锛�2瀛楄妭锛堣窛2000-01-01鐨勫ぉ鏁帮級
+    stream << dateToDays(expireDate);
+
+    // 5. 浜у搧鍙凤細1瀛楄妭
+    stream << productId;
+
+    // 6. 鐗堟湰鍙凤細涓荤増鏈� + 娆$増鏈紝鍚�1瀛楄妭
+    stream << verMajor << verMinor;
+
+    // 7. 婵�娲荤姸鎬侊細1瀛楄妭
+    stream << activeState;
+
+    return data;
+}
+
+bool LicenseData::fromBinary(const QByteArray &data)
+{
+    if (data.size() < 30) {
+        qWarning() << "LicenseData::fromBinary: data too short, need at least 30 bytes";
+        return false;
+    }
+
+    QDataStream stream(data);
+    stream.setByteOrder(QDataStream::BigEndian);
+
+    // 1. UUID
+    boardUuid.resize(16);
+    stream.readRawData(boardUuid.data(), 16);
+
+    // 2. CPU搴忓垪鍙�
+    cpuSerial.resize(8);
+    stream.readRawData(cpuSerial.data(), 8);
+
+    // 3. 鐢ㄦ埛鍚�
+    quint8 nameLen = 0;
+    stream >> nameLen;
+    if (data.size() < 25 + nameLen + 5) {
+        qWarning() << "LicenseData::fromBinary: insufficient data for remaining fields";
+        return false;
+    }
+    QByteArray userBytes(nameLen, '\0');
+    stream.readRawData(userBytes.data(), nameLen);
+    userName = QString::fromUtf8(userBytes);
+
+    // 4. 鏃ユ湡
+    quint16 days = 0;
+    stream >> days;
+    expireDate = daysToDate(days);
+
+    // 5. 浜у搧鍙�
+    stream >> productId;
+
+    // 6. 鐗堟湰
+    stream >> verMajor >> verMinor;
+
+    // 7. 婵�娲荤姸鎬�
+    stream >> activeState;
+
+    return true;
+}
+
+QString LicenseData::toDebugString() const
+{
+    return QString("{UUID:%1, CPU:%2, User:%3, Expire:%4, Prod:%5, Ver:%6.%7, State:%8}")
+        .arg(uuidBinaryToString(boardUuid))
+        .arg(binaryToHexString(cpuSerial))
+        .arg(userName)
+        .arg(expireDate.toString("yyyy-MM-dd"))
+        .arg(productId)
+        .arg(verMajor).arg(verMinor)
+        .arg(activeState);
+}
+
+quint16 LicenseData::dateToDays(const QDate &date) const
+{
+    QDate base(BASE_YEAR, BASE_MONTH, BASE_DAY);
+    if (!date.isValid() || date < base) {
+        return 0;
+    }
+    return static_cast<quint16>(base.daysTo(date));
+}
+
+QDate LicenseData::daysToDate(quint16 days) const
+{
+    QDate base(BASE_YEAR, BASE_MONTH, BASE_DAY);
+    return base.addDays(days);
+}
+
+QByteArray LicenseData::uuidStringToBinary(const QString &uuidStr)
+{
+    QString clean = uuidStr;
+    clean.remove('-');
+    clean.remove('{');
+    clean.remove('}');
+    clean = clean.toUpper();
+    if (clean.size() != 32) {
+        return QByteArray();
+    }
+    return hexStringToBinary(clean);
+}
+
+QString LicenseData::uuidBinaryToString(const QByteArray &bin)
+{
+    if (bin.size() != 16) {
+        return QString();
+    }
+    QString hex = binaryToHexString(bin);
+    return QString("%1-%2-%3-%4-%5")
+        .arg(hex.mid(0, 8))
+        .arg(hex.mid(8, 4))
+        .arg(hex.mid(12, 4))
+        .arg(hex.mid(16, 4))
+        .arg(hex.mid(20, 12));
+}
+
+QByteArray LicenseData::hexStringToBinary(const QString &hexStr)
+{
+    QString clean = hexStr;
+    clean.remove(' ');
+    QByteArray result;
+    result.reserve(clean.size() / 2);
+    for (int i = 0; i + 1 < clean.size(); i += 2) {
+        bool ok;
+        result.append(static_cast<char>(clean.mid(i, 2).toUInt(&ok, 16)));
+    }
+    return result;
+}
+
+QString LicenseData::binaryToHexString(const QByteArray &bin)
+{
+    return QString::fromLatin1(bin.toHex()).toUpper();
+}
diff --git a/licensedata.h b/licensedata.h
new file mode 100644
index 0000000..e732d3d
--- /dev/null
+++ b/licensedata.h
@@ -0,0 +1,57 @@
+锘�#ifndef LICENSEDATA_H
+#define LICENSEDATA_H
+
+#include <QByteArray>
+#include <QString>
+#include <QDate>
+
+/**
+ * @brief 璁稿彲璇佹暟鎹粨鏋� V2锛堟瀬鑷寸揣鍑戠増锛�
+ *
+ * 浜岃繘鍒舵牸寮忥紙澶х搴忥級锛�
+ *  [0..15]   16B  涓绘澘UUID锛堝師濮嬩簩杩涘埗锛�
+ *  [16..23]   8B  CPU搴忓垪鍙凤紙鍘熷浜岃繘鍒讹級
+ *  [24]       1B  鐢ㄦ埛鍚嶉暱搴
+ *  [25..24+N] N B  鐢ㄦ埛鍚峌TF-8鏁版嵁
+ *  [25+N..26+N] 2B  澶辨晥鏃ユ湡锛堣窛2000-01-01鐨勫ぉ鏁帮紝uint16锛�
+ *  [27+N]     1B  浜у搧鍙凤紙uint8锛�
+ *  [28+N]     1B  涓荤増鏈彿锛坲int8锛�
+ *  [29+N]     1B  娆$増鏈彿锛坲int8锛�
+ *  [30+N]     1B  婵�娲荤姸鎬侊紙uint8锛�
+ *
+ * 鎬婚暱搴� = 31 + N 瀛楄妭
+ */
+struct LicenseData
+{
+    QByteArray boardUuid;    // 16瀛楄妭浜岃繘鍒禪UID
+    QByteArray cpuSerial;    // 8瀛楄妭浜岃繘鍒�
+    QString    userName;     // 鐢ㄦ埛鍚�
+    QDate      expireDate;   // 澶辨晥鏃ユ湡锛堜粎鏃ユ湡锛屾棤鏃堕棿锛�
+    quint8     productId;    // 浜у搧鍙�
+    quint8     verMajor;     // 涓荤増鏈彿
+    quint8     verMinor;     // 娆$増鏈彿
+    quint8     activeState;  // 婵�娲荤姸鎬�
+
+    LicenseData();
+
+    QByteArray toBinary() const;
+    bool fromBinary(const QByteArray &data);
+    QString toDebugString() const;
+
+    // 杈呭姪杞崲
+    static QByteArray uuidStringToBinary(const QString &uuidStr);
+    static QString    uuidBinaryToString(const QByteArray &bin);
+    static QByteArray hexStringToBinary(const QString &hexStr);
+    static QString    binaryToHexString(const QByteArray &bin);
+
+private:
+    // 鏃ユ湡鍩哄噯锛�2000-01-01锛岀敤uint16瀛樺ぉ鏁帮紝鑼冨洿 2000-01-01 ~ 2182-06-05
+    static constexpr int BASE_YEAR = 2000;
+    static constexpr int BASE_MONTH = 1;
+    static constexpr int BASE_DAY = 1;
+
+    quint16 dateToDays(const QDate &date) const;
+    QDate daysToDate(quint16 days) const;
+};
+
+#endif // LICENSEDATA_H
diff --git a/mainwindow.cpp b/mainwindow.cpp
index 9499d6c..1292e42 100644
--- a/mainwindow.cpp
+++ b/mainwindow.cpp
@@ -1,6 +1,8 @@
 锘�#include "mainwindow.h"
 #include "ui_mainwindow.h"
 #include "qaesencryption.h"
+#include "licensedata.h"
+#include "shortcrypto.h"
 
 #include <QClipboard>
 #include <QDateTime>
@@ -48,6 +50,12 @@
     ui->label_biosnum->setVisible(false);
     ui->label_basenum_2->setVisible(false);
     ui->label_biosnum_2->setVisible(false);
+    QTextOption opt = ui->textEdit_localid->document()->defaultTextOption();
+    opt.setWrapMode(QTextOption::WrapAnywhere);
+    ui->textEdit_localid->document()->setDefaultTextOption(opt);
+    QTextOption opt_lic = ui->textEdit_licensekey->document()->defaultTextOption();
+    opt_lic.setWrapMode(QTextOption::WrapAnywhere);
+    ui->textEdit_licensekey->document()->setDefaultTextOption(opt_lic);
     //鍓嶄竷鏉℃槸绠�鍖栧姞瀵嗘暟鎹繀鐢ㄧ殑,鍦ㄨ繖閲岃瀹氬ソ鏂逛究瀵瑰簲
     m_numToInfo.insert("1","Baseboard_Uuid");
     m_numToInfo.insert("2","CPU_Processorid");
@@ -269,57 +277,73 @@
 void MainWindow::on_pushButton_decrypt_clicked()
 {
     QString encryptlocalid = ui->textEdit_localid->toPlainText();
-    QString localid = getDecrypt(encryptlocalid,key);
-    QByteArray localidbyte = localid.toLocal8Bit();
-    QJsonParseError err_rpt;
-    QJsonDocument localidjsondoc(QJsonDocument::fromJson(localid.toUtf8(), &err_rpt));//瀛楃涓叉牸寮忓寲涓篔SON
-    if(err_rpt.error != QJsonParseError::NoError)
-    {
-        localinfo = LicenseInfo();
-        licenseinfo = LicenseInfo();
-        workingjsondoc = QJsonDocument();
-        ui->textEdit_licensekey->setPlainText("");
-        changeUIstate();
-        qDebug() << QStringLiteral("localid JSON鏍煎紡閿欒");
-        QMessageBox msgbox(QMessageBox::Information,QStringLiteral(""),QStringLiteral("瑙f瀽澶辫触锛屼笉鏄竴涓纭殑璁惧ID搴忓垪"),QMessageBox::Ok);
-        msgbox.setButtonText(QMessageBox::Ok,QStringLiteral("纭畾"));
-        msgbox.exec();
-    }
-    else    //JSON鏍煎紡姝g‘
-    {
-        QMessageBox msgbox(QMessageBox::Information,QStringLiteral(""),QStringLiteral("瑙f瀽鎴愬姛"),QMessageBox::Ok);
-        msgbox.setButtonText(QMessageBox::Ok,QStringLiteral("纭畾"));
-        msgbox.exec();
-        ui->textEdit_licensekey->setPlainText(ui->textEdit_localid->toPlainText());
-        workingjsondoc = QJsonDocument(QJsonDocument::fromJson(localidbyte));
+    // 涓�閿В瀵�
+    lic2.fromBinary(ShortCrypto::decrypt(encryptlocalid, key));
+    qDebug()<<"on_pushButton_decrypt_clicked"<<lic2.toDebugString();
+    //涓庝箣鍓嶇殑鍔犲瘑瀵瑰簲,涓斿幓鎺夊啑浣欎俊鎭�
+    localinfo.Baseboard_Uuid = LicenseData::uuidBinaryToString(lic2.boardUuid);
+    localinfo.CPU_Processorid = LicenseData::binaryToHexString(lic2.cpuSerial);
+    localinfo.Username = lic2.userName;
+    localinfo.LicensedDuration_end = lic2.expireDate.toString("yyyy-MM-dd");
+//    localinfo.LicensedDuration_start = localid_Obj.value(m_numToInfo.key("LicensedDuration_start")).toString();
+    localinfo.Productid = QString::number(lic2.productId);
+    localinfo.Versionid = QString::number(lic2.verMajor)+"."+QString::number(lic2.verMinor);
+    localinfo.ActiveState = static_cast<int>(lic2.activeState);
+    licenseinfo = LicenseInfo(localinfo);
+    ui->textEdit_licensekey->setPlainText(ui->textEdit_localid->toPlainText());
+    changeUIstate();
 
-        QJsonObject localid_Obj = localidjsondoc.object();
-//        localinfo.Baseboard_Serialnumber = localid_Obj.value("Baseboard_Serialnumber").toString();
-//        localinfo.Baseboard_Uuid = localid_Obj.value("Baseboard_Uuid").toString();
-//        localinfo.Bios_Serialnumber = localid_Obj.value("Bios_Serialnumber").toString();
-//        localinfo.CPU_Processorid = localid_Obj.value("CPU_Processorid").toString();
-//        localinfo.Username = localid_Obj.value("Username").toString();
-//        localinfo.IsEnabled_cell = localid_Obj.value("IsEnabled_cell").toInt();
-//        localinfo.IsEnabled_aquifer = localid_Obj.value("IsEnabled_aquifer").toInt();
-//        localinfo.IsEnabled_pipe = localid_Obj.value("IsEnabled_pipe").toInt();
-//        localinfo.IsEnabled_network = localid_Obj.value("IsEnabled_network").toInt();
-//        localinfo.LicensedDuration_end = localid_Obj.value("LicensedDuration_end").toString();
-//        localinfo.LicensedDuration_start = localid_Obj.value("LicensedDuration_start").toString();
-//        localinfo.Productid = localid_Obj.value("Productid").toString();
-//        localinfo.Versionid = localid_Obj.value("Versionid").toString();
+//    QString localid = getDecrypt(encryptlocalid,key);
+//    QByteArray localidbyte = localid.toLocal8Bit();
+//    QJsonParseError err_rpt;
+//    QJsonDocument localidjsondoc(QJsonDocument::fromJson(localid.toUtf8(), &err_rpt));//瀛楃涓叉牸寮忓寲涓篔SON
+//    if(err_rpt.error != QJsonParseError::NoError)
+//    {
+//        localinfo = LicenseInfo();
+//        licenseinfo = LicenseInfo();
+//        workingjsondoc = QJsonDocument();
+//        ui->textEdit_licensekey->setPlainText("");
+//        changeUIstate();
+//        qDebug() << QStringLiteral("localid JSON鏍煎紡閿欒");
+//        QMessageBox msgbox(QMessageBox::Information,QStringLiteral(""),QStringLiteral("瑙f瀽澶辫触锛屼笉鏄竴涓纭殑璁惧ID搴忓垪"),QMessageBox::Ok);
+//        msgbox.setButtonText(QMessageBox::Ok,QStringLiteral("纭畾"));
+//        msgbox.exec();
+//    }
+//    else    //JSON鏍煎紡姝g‘
+//    {
+//        QMessageBox msgbox(QMessageBox::Information,QStringLiteral(""),QStringLiteral("瑙f瀽鎴愬姛"),QMessageBox::Ok);
+//        msgbox.setButtonText(QMessageBox::Ok,QStringLiteral("纭畾"));
+//        msgbox.exec();
+//        ui->textEdit_licensekey->setPlainText(ui->textEdit_localid->toPlainText());
+//        workingjsondoc = QJsonDocument(QJsonDocument::fromJson(localidbyte));
 
-        //涓庝箣鍓嶇殑鍔犲瘑瀵瑰簲,涓斿幓鎺夊啑浣欎俊鎭�
-        localinfo.Baseboard_Uuid = localid_Obj.value(m_numToInfo.key("Baseboard_Uuid")).toString();
-        localinfo.CPU_Processorid = localid_Obj.value(m_numToInfo.key("CPU_Processorid")).toString();
-        localinfo.Username = localid_Obj.value(m_numToInfo.key("Username")).toString();
-        localinfo.LicensedDuration_end = localid_Obj.value(m_numToInfo.key("LicensedDuration_end")).toString();
-        localinfo.LicensedDuration_start = localid_Obj.value(m_numToInfo.key("LicensedDuration_start")).toString();
-        localinfo.Productid = localid_Obj.value(m_numToInfo.key("Productid")).toString();
-        localinfo.Versionid = localid_Obj.value(m_numToInfo.key("Versionid")).toString();
-        localinfo.ActiveState = localid_Obj.value(m_numToInfo.key("ActiveState")).toInt();
-        licenseinfo = LicenseInfo(localinfo);
-        changeUIstate();
-    }
+//        QJsonObject localid_Obj = localidjsondoc.object();
+////        localinfo.Baseboard_Serialnumber = localid_Obj.value("Baseboard_Serialnumber").toString();
+////        localinfo.Baseboard_Uuid = localid_Obj.value("Baseboard_Uuid").toString();
+////        localinfo.Bios_Serialnumber = localid_Obj.value("Bios_Serialnumber").toString();
+////        localinfo.CPU_Processorid = localid_Obj.value("CPU_Processorid").toString();
+////        localinfo.Username = localid_Obj.value("Username").toString();
+////        localinfo.IsEnabled_cell = localid_Obj.value("IsEnabled_cell").toInt();
+////        localinfo.IsEnabled_aquifer = localid_Obj.value("IsEnabled_aquifer").toInt();
+////        localinfo.IsEnabled_pipe = localid_Obj.value("IsEnabled_pipe").toInt();
+////        localinfo.IsEnabled_network = localid_Obj.value("IsEnabled_network").toInt();
+////        localinfo.LicensedDuration_end = localid_Obj.value("LicensedDuration_end").toString();
+////        localinfo.LicensedDuration_start = localid_Obj.value("LicensedDuration_start").toString();
+////        localinfo.Productid = localid_Obj.value("Productid").toString();
+////        localinfo.Versionid = localid_Obj.value("Versionid").toString();
+
+//        //涓庝箣鍓嶇殑鍔犲瘑瀵瑰簲,涓斿幓鎺夊啑浣欎俊鎭�
+//        localinfo.Baseboard_Uuid = localid_Obj.value(m_numToInfo.key("Baseboard_Uuid")).toString();
+//        localinfo.CPU_Processorid = localid_Obj.value(m_numToInfo.key("CPU_Processorid")).toString();
+//        localinfo.Username = localid_Obj.value(m_numToInfo.key("Username")).toString();
+//        localinfo.LicensedDuration_end = localid_Obj.value(m_numToInfo.key("LicensedDuration_end")).toString();
+//        localinfo.LicensedDuration_start = localid_Obj.value(m_numToInfo.key("LicensedDuration_start")).toString();
+//        localinfo.Productid = localid_Obj.value(m_numToInfo.key("Productid")).toString();
+//        localinfo.Versionid = localid_Obj.value(m_numToInfo.key("Versionid")).toString();
+//        localinfo.ActiveState = localid_Obj.value(m_numToInfo.key("ActiveState")).toInt();
+//        licenseinfo = LicenseInfo(localinfo);
+//        changeUIstate();
+//    }
 }
 
 void MainWindow::on_pushButton_accreditall_clicked()
@@ -505,31 +529,25 @@
 
 void MainWindow::giveLicense(int time)
 {
-    QJsonObject licensekey_Obj = workingjsondoc.object();
-//    licensekey_Obj[m_numToInfo.key("IsEnabled_cell")] = 1;
-//    licensekey_Obj[m_numToInfo.key("IsEnabled_aquifer")] = 1;
-//    licensekey_Obj[m_numToInfo.key("IsEnabled_pipe")] = 1;
-//    licensekey_Obj[m_numToInfo.key("IsEnabled_network")] = 1;
-    licensekey_Obj[m_numToInfo.key("ActiveState")] = 1;
-//    QDateTime licensedate = QDateTime::fromString(licensekey_Obj[m_numToInfo.key("LicensedDuration_end")].toString(),"yyyy-MM-dd hh:mm:ss");
-//    if(licensedate.isNull()){
-//        qDebug()<<"licenseTime is Null";
-//        licensedate = QDateTime::currentDateTime();
-//    }
     //鐜板湪鐐瑰嚮鎺堟潈鏄粠褰撳墠鐨勬椂闂村姞鎺堟潈鏃堕棿
     QDateTime licensedate = QDateTime::currentDateTime();
     QDateTime newlicensedate = licensedate.addMonths(time);
-    QString licensedatestr = newlicensedate.toString("yyyy-MM-dd hh:mm:ss");
-    licensekey_Obj[m_numToInfo.key("LicensedDuration_start")] = licensedate.toString("yyyy-MM-dd hh:mm:ss");
-    licensekey_Obj[m_numToInfo.key("LicensedDuration_end")] = licensedatestr;
-    workingjsondoc.setObject(licensekey_Obj);
-    //鏁版嵁鍘嬬缉锛屽幓绌烘牸鎹㈣绛夊浣欐棤鐢ㄤ俊鎭�
-    QByteArray compressedArray = QJsonDocument(licensekey_Obj).toJson(QJsonDocument::Compact);
-    QByteArray jsonbytearray = qCompress(compressedArray,9);
-    QString testid = jsonbytearray.toBase64();
-    ui->textEdit_licensekey->setPlainText("");
-    ui->textEdit_licensekey->setPlainText(getEncrypt(QString(testid),key));
-    setLicenseinfo(licensekey_Obj);
+    QString licensedatestr = newlicensedate.toString("yyyy-MM-dd");
+    lic2.expireDate = QDate::fromString(licensedatestr,"yyyy-MM-dd");
+//    lic2.expireDate = lic2.expireDate.addMonths(time);
+    lic2.activeState = 1;
+    QString cipher = ShortCrypto::encrypt(lic2.toBinary(), key);
+    ui->textEdit_licensekey->clear();
+    ui->textEdit_licensekey->setPlainText(cipher);
+    // 涓�閿В瀵�
+    LicenseData lic3;
+    lic3.fromBinary(ShortCrypto::decrypt(cipher, key));
+    qDebug()<<"change"<<cipher<<lic3.toDebugString()<<cipher.size();
+    //鏇存柊licenseinfo锛屽彧闇�瑕佹洿鏂癓icensedDuration_end銆丩icensedDuration_start銆丄ctiveState
+    licenseinfo.LicensedDuration_end = newlicensedate.toString("yyyy-MM-dd");
+    licenseinfo.LicensedDuration_start = licensedate.toString("yyyy-MM-dd");
+    licenseinfo.ActiveState = 1;
+    changeUIstate();
     //灏嗘巿鏉冧俊鎭褰曞埌excel琛ㄤ腑
     QString edition ="";
     if(time == 3){
@@ -539,12 +557,12 @@
     }else if(time == 12){
         edition = QStringLiteral("涓撲笟鐗�");
     }
-    ActiveRecord(licensekey_Obj,edition,ui->textEdit_licensekey->toPlainText());
+    ActiveRecord(lic2,edition,ui->textEdit_licensekey->toPlainText());
 }
 
-void MainWindow::ActiveRecord(QJsonObject jsonObj,QString edition, QString licenseKey)
+void MainWindow::ActiveRecord(LicenseData lic,QString edition, QString licenseKey)
 {
-    QString Baseboard_Uuid = jsonObj[m_numToInfo.key("Baseboard_Uuid")].toString();
+    QString Baseboard_Uuid = LicenseData::uuidBinaryToString(lic.boardUuid);
     QString src = QApplication::applicationDirPath();
     QDir dir(src);
     QString file_name(QStringLiteral("瀹夊叏璇勪环杞欢鎺堟潈浜烘暟缁熻琛�.xlsx"));
@@ -587,24 +605,58 @@
         int rowCount = xlsx.dimension().rowCount()+1;
         int id = xlsx.read(rowCount-1,1).toInt();
         xlsx.write(rowCount, 1, id+1);
-        xlsx.write(rowCount, 2, jsonObj[m_numToInfo.key("Baseboard_Uuid")].toString());
+        xlsx.write(rowCount, 2, LicenseData::uuidBinaryToString(lic.boardUuid));
         xlsx.write(rowCount, 3, edition);
-        xlsx.write(rowCount, 4, jsonObj[m_numToInfo.key("LicensedDuration_start")].toString());
-        xlsx.write(rowCount, 5, jsonObj[m_numToInfo.key("LicensedDuration_end")].toString());
-        xlsx.write(rowCount, 6, jsonObj[m_numToInfo.key("Productid")].toString());
-        xlsx.write(rowCount, 7, jsonObj[m_numToInfo.key("Versionid")].toString());
+        xlsx.write(rowCount, 4, QDate::currentDate().toString("yyyy-MM-dd"));
+        xlsx.write(rowCount, 5, lic.expireDate.toString("yyyy-MM-dd"));
+        xlsx.write(rowCount, 6, QString::number(lic2.productId));
+        xlsx.write(rowCount, 7, QString::number(lic2.verMajor)+"."+QString::number(lic2.verMinor));
         xlsx.write(rowCount, 8, licenseKey);
     }else{
         //濡傛灉瀛樺湪杩欐潯璁板綍灏辨洿鏂版暟鎹俊鎭�
-        xlsx.write(uuidColumn, 2, jsonObj[m_numToInfo.key("Baseboard_Uuid")].toString());
+        xlsx.write(uuidColumn, 2, LicenseData::uuidBinaryToString(lic.boardUuid));
         xlsx.write(uuidColumn, 3, edition);
-        xlsx.write(uuidColumn, 4, jsonObj[m_numToInfo.key("LicensedDuration_start")].toString());
-        xlsx.write(uuidColumn, 5, jsonObj[m_numToInfo.key("LicensedDuration_end")].toString());
-        xlsx.write(uuidColumn, 6, jsonObj[m_numToInfo.key("Productid")].toString());
-        xlsx.write(uuidColumn, 7, jsonObj[m_numToInfo.key("Versionid")].toString());
+        xlsx.write(uuidColumn, 4, QDate::currentDate().toString("yyyy-MM-dd"));
+        xlsx.write(uuidColumn, 5, lic.expireDate.toString("yyyy-MM-dd"));
+        xlsx.write(uuidColumn, 6, QString::number(lic2.productId));
+        xlsx.write(uuidColumn, 7, QString::number(lic2.verMajor)+"."+QString::number(lic2.verMinor));
         xlsx.write(uuidColumn, 8, licenseKey);
     }
     xlsx.save();
+}
+
+QString MainWindow::getEncrypt_New()
+{
+    QString localid = "";
+    LicenseInfo localinfo;
+    //鏌ヨ绯荤粺鐢ㄦ埛鍚�
+    localinfo.Username = qgetenv("USER"); // Linux绯荤粺
+    if (localinfo.Username.isEmpty())
+        localinfo.Username = qgetenv("USERNAME"); // Windows绯荤粺
+    //鏌ヨCPU搴忓垪鍙�
+    localinfo.CPU_Processorid = getWindowsInfo("wmic cpu get processorid");
+    //鏌ヨ涓绘澘搴忓垪鍙�
+    localinfo.Baseboard_Serialnumber = getWindowsInfo("wmic baseboard get serialnumber");
+    //鏌ヨBIOS搴忓垪鍙�
+    localinfo.Bios_Serialnumber = getWindowsInfo("wmic bios get serialnumber");
+    //鏌ヨ涓绘澘鍞竴鏍囪瘑
+    localinfo.Baseboard_Uuid = getWindowsInfo("wmic csproduct get uuid");
+
+    //灏濊瘯鏂扮殑鍔犲瘑鏂规硶
+    LicenseData lic;
+    lic.boardUuid  = LicenseData::hexStringToBinary(localinfo.Baseboard_Uuid);
+    lic.cpuSerial  = LicenseData::hexStringToBinary(localinfo.CPU_Processorid);
+    lic.userName   = localinfo.Username;
+    lic.expireDate = QDate::fromString(localinfo.LicensedDuration_end,"yyyy-MM-dd");
+    lic.productId  = localinfo.Productid.toUInt();
+    QString version = localinfo.Versionid;
+    lic.verMajor   = version.split(".").at(0).toUInt();
+    lic.verMinor   = version.split(".").at(1).toUInt();
+    lic.activeState = localinfo.ActiveState;
+    // 涓�閿姞瀵�
+    QString cipher = ShortCrypto::encrypt(lic.toBinary(), key);
+//    ui->textEdit_localid->setText(cipher);
+    return  cipher;
 }
 
 
@@ -612,6 +664,9 @@
 {
     QString localid = getLocalID();
     QString encryptid = getEncrypt(localid,key);
+
+    //鏂扮殑鍔犲瘑鏂规硶
+    encryptid = getEncrypt_New();
     ui->textEdit_localid->setText(encryptid);
 
     localinfo = LicenseInfo();
@@ -725,38 +780,48 @@
 
 void MainWindow::on_pushButton_setproid_clicked()
 {
-    QJsonObject licensekey_Obj = workingjsondoc.object();
-    licensekey_Obj[m_numToInfo.key("Productid")] = ui->lineEdit_setproid->text();
-    workingjsondoc.setObject(licensekey_Obj);
+//    QJsonObject licensekey_Obj = workingjsondoc.object();
+//    licensekey_Obj[m_numToInfo.key("Productid")] = ui->lineEdit_setproid->text();
+//    workingjsondoc.setObject(licensekey_Obj);
 
-    QByteArray compressedArray = QJsonDocument(licensekey_Obj).toJson(QJsonDocument::Compact);
-    QByteArray jsonbytearray = qCompress(compressedArray,9);
-    QString testid = jsonbytearray.toBase64();
-    ui->textEdit_licensekey->setPlainText("");
-    ui->textEdit_licensekey->setPlainText(getEncrypt(QString(testid),key));
-
-//    QByteArray jsonbytearray = workingjsondoc.toJson();
+//    QByteArray compressedArray = QJsonDocument(licensekey_Obj).toJson(QJsonDocument::Compact);
+//    QByteArray jsonbytearray = qCompress(compressedArray,9);
+//    QString testid = jsonbytearray.toBase64();
 //    ui->textEdit_licensekey->setPlainText("");
-//    ui->textEdit_licensekey->setPlainText(getEncrypt(QString(jsonbytearray),key));
-    setLicenseinfo(licensekey_Obj);
+//    ui->textEdit_licensekey->setPlainText(getEncrypt(QString(testid),key));
+
+    lic2.productId = ui->lineEdit_setproid->text().toUInt();
+    QString cipher = ShortCrypto::encrypt(lic2.toBinary(), key);
+    ui->textEdit_licensekey->setPlainText(cipher);
+//    setLicenseinfo(licensekey_Obj);
+
+    //閫欒!涔熷彧闇�瑕佹洿鏂皃roductId
+    licenseinfo.Productid = ui->lineEdit_setproid->text();
+    changeUIstate();
+
 }
 
 void MainWindow::on_pushButton_setversion_clicked()
 {
-    QJsonObject licensekey_Obj = workingjsondoc.object();
-    licensekey_Obj[m_numToInfo.key("Versionid")] = ui->lineEdit_setversion->text();
-    workingjsondoc.setObject(licensekey_Obj);
+//    QJsonObject licensekey_Obj = workingjsondoc.object();
+//    licensekey_Obj[m_numToInfo.key("Versionid")] = ui->lineEdit_setversion->text();
+//    workingjsondoc.setObject(licensekey_Obj);
 
-    QByteArray compressedArray = QJsonDocument(licensekey_Obj).toJson(QJsonDocument::Compact);
-    QByteArray jsonbytearray = qCompress(compressedArray,9);
-    QString testid = jsonbytearray.toBase64();
-    ui->textEdit_licensekey->setPlainText("");
-    ui->textEdit_licensekey->setPlainText(getEncrypt(QString(testid),key));
-
-//    QByteArray jsonbytearray = workingjsondoc.toJson();
+//    QByteArray compressedArray = QJsonDocument(licensekey_Obj).toJson(QJsonDocument::Compact);
+//    QByteArray jsonbytearray = qCompress(compressedArray,9);
+//    QString testid = jsonbytearray.toBase64();
 //    ui->textEdit_licensekey->setPlainText("");
-//    ui->textEdit_licensekey->setPlainText(getEncrypt(QString(jsonbytearray),key));
-    setLicenseinfo(licensekey_Obj);
+//    ui->textEdit_licensekey->setPlainText(getEncrypt(QString(testid),key));
+
+//    setLicenseinfo(licensekey_Obj);
+    QString version = ui->lineEdit_setversion->text();
+    lic2.verMajor = version.split(".").at(0).toUInt();
+    lic2.verMinor = version.split(".").at(1).toUInt();
+    QString cipher = ShortCrypto::encrypt(lic2.toBinary(), key);
+    ui->textEdit_licensekey->setPlainText(cipher);
+    //閫欒!涔熷彧闇�瑕佹洿鏂癡ersionid
+    licenseinfo.Versionid = ui->lineEdit_setversion->text();
+    changeUIstate();
 }
 
 void MainWindow::on_pushButton_normal_clicked()
diff --git a/mainwindow.h b/mainwindow.h
index 56bec37..2edb142 100644
--- a/mainwindow.h
+++ b/mainwindow.h
@@ -1,6 +1,8 @@
 锘�#ifndef MAINWINDOW_H
 #define MAINWINDOW_H
 
+#include "licensedata.h"
+
 #include <QMainWindow>
 #include <QCryptographicHash>
 #include <QJsonDocument>
@@ -22,10 +24,10 @@
     int IsEnabled_aquifer = 0;
     int IsEnabled_pipe = 0;
     int IsEnabled_network = 0;
-    QString LicensedDuration_start = "2023-04-01 12:00:00";
-    QString LicensedDuration_end = "2023-04-01 12:00:00";
+    QString LicensedDuration_start = "2023-04-01";
+    QString LicensedDuration_end = "2023-04-01";
     QString Productid = "1"; //浜у搧鍙� 锛�1锛�3锛夊畨鍏ㄨ瘎浠疯蒋浠讹紙2锛�3锛夋暟鎹簱
-    QString Versionid = "1.0.0.0"; //鐗堟湰鍙� 鐢ㄤ簬鍖哄垎澶х増鏈紝鍚屼竴涓ぇ鐗堟湰鍐呭彲鐢�
+    QString Versionid = "2.0"; //鐗堟湰鍙� 鐢ㄤ簬鍖哄垎澶х増鏈紝鍚屼竴涓ぇ鐗堟湰鍐呭彲鐢�
 } LicenseInfo;
 
 class MainWindow : public QMainWindow
@@ -65,8 +67,10 @@
 
     //鎺堟潈闆嗕腑鍦ㄤ竴璧凤紝涓嶅悓鐐瑰湪浜庢椂闂�
     void giveLicense(int time);
-    void ActiveRecord(QJsonObject jsonObj,QString edition, QString licenseKey);
+    void ActiveRecord(LicenseData lic,QString edition, QString licenseKey);
 
+    //鏂扮殑鍔犲瘑鏂规硶
+    QString getEncrypt_New();
 private slots:
     void on_pushButton_decrypt_clicked();
 
@@ -118,7 +122,11 @@
 
     QJsonDocument workingjsondoc;
 
-    QString key = "9aFUEFjsqHsde4DOhirdskgdznSDHlfb0ae";
+    LicenseData lic2;
+    QByteArray key = "MySecretKey12345";
+
+//    QString key = "9aFUEFjsqHsde4DOhirdskgdznSDHlfb0ae";
+//    QByteArray key = "MySecretKey12345";  // 16瀛楄妭瀵嗛挜
 
     QMap<QString,QString> m_numToInfo;
 };
diff --git a/mainwindow.ui b/mainwindow.ui
index 3ec71f6..a17d8fe 100644
--- a/mainwindow.ui
+++ b/mainwindow.ui
@@ -39,33 +39,6 @@
       <layout class="QGridLayout" name="gridLayout_3">
        <item row="0" column="0">
         <layout class="QGridLayout" name="gridLayout_2">
-         <item row="0" column="1" rowspan="2" colspan="3">
-          <widget class="QTextEdit" name="textEdit_licensekey">
-           <property name="readOnly">
-            <bool>true</bool>
-           </property>
-          </widget>
-         </item>
-         <item row="2" column="3">
-          <widget class="QPushButton" name="pushButton_copykey">
-           <property name="text">
-            <string>澶嶅埗瀵嗛挜</string>
-           </property>
-          </widget>
-         </item>
-         <item row="1" column="0">
-          <spacer name="verticalSpacer_2">
-           <property name="orientation">
-            <enum>Qt::Vertical</enum>
-           </property>
-           <property name="sizeHint" stdset="0">
-            <size>
-             <width>20</width>
-             <height>40</height>
-            </size>
-           </property>
-          </spacer>
-         </item>
          <item row="2" column="1">
           <spacer name="horizontalSpacer_2">
            <property name="orientation">
@@ -86,10 +59,40 @@
            </property>
           </widget>
          </item>
+         <item row="0" column="1" rowspan="2" colspan="3">
+          <widget class="QTextEdit" name="textEdit_licensekey">
+           <property name="lineWrapMode">
+            <enum>QTextEdit::WidgetWidth</enum>
+           </property>
+           <property name="readOnly">
+            <bool>true</bool>
+           </property>
+          </widget>
+         </item>
          <item row="2" column="2">
           <widget class="QPushButton" name="pushButton_export">
            <property name="text">
             <string>瀵煎嚭鏂囨湰</string>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="0">
+          <spacer name="verticalSpacer_2">
+           <property name="orientation">
+            <enum>Qt::Vertical</enum>
+           </property>
+           <property name="sizeHint" stdset="0">
+            <size>
+             <width>20</width>
+             <height>40</height>
+            </size>
+           </property>
+          </spacer>
+         </item>
+         <item row="2" column="3">
+          <widget class="QPushButton" name="pushButton_copykey">
+           <property name="text">
+            <string>澶嶅埗瀵嗛挜</string>
            </property>
           </widget>
          </item>
@@ -100,50 +103,13 @@
     </item>
     <item row="2" column="0">
      <layout class="QGridLayout" name="gridLayout_6">
-      <item row="5" column="0">
-       <widget class="QPushButton" name="pushButton_setproid">
+      <item row="3" column="0">
+       <widget class="QPushButton" name="pushButton_deaccreditall">
         <property name="enabled">
          <bool>false</bool>
         </property>
         <property name="text">
-         <string>璁剧疆浜у搧鍙�</string>
-        </property>
-       </widget>
-      </item>
-      <item row="3" column="1">
-       <widget class="QPushButton" name="pushButton_accreditpipe">
-        <property name="enabled">
-         <bool>false</bool>
-        </property>
-        <property name="text">
-         <string>鎺堟潈鍗曡闅�</string>
-        </property>
-       </widget>
-      </item>
-      <item row="4" column="1">
-       <widget class="QPushButton" name="pushButton_adddate">
-        <property name="enabled">
-         <bool>false</bool>
-        </property>
-        <property name="text">
-         <string>+1涓湀</string>
-        </property>
-       </widget>
-      </item>
-      <item row="1" column="0">
-       <widget class="QPushButton" name="pushButton_normal">
-        <property name="text">
-         <string>鎺堟潈鏅�氱増</string>
-        </property>
-       </widget>
-      </item>
-      <item row="2" column="0">
-       <widget class="QPushButton" name="pushButton_accreditall">
-        <property name="enabled">
-         <bool>false</bool>
-        </property>
-        <property name="text">
-         <string>鎺堟潈鎵�鏈夋ā鍧�</string>
+         <string>瑙i櫎鎵�鏈夋巿鏉�</string>
         </property>
        </widget>
       </item>
@@ -157,61 +123,13 @@
         </property>
        </widget>
       </item>
-      <item row="2" column="2">
-       <widget class="QPushButton" name="pushButton_accreditaquifer">
+      <item row="4" column="1">
+       <widget class="QPushButton" name="pushButton_adddate">
         <property name="enabled">
          <bool>false</bool>
         </property>
         <property name="text">
-         <string>鎺堟潈鍚按閫氶亾</string>
-        </property>
-       </widget>
-      </item>
-      <item row="3" column="0">
-       <widget class="QPushButton" name="pushButton_deaccreditall">
-        <property name="enabled">
-         <bool>false</bool>
-        </property>
-        <property name="text">
-         <string>瑙i櫎鎵�鏈夋巿鏉�</string>
-        </property>
-       </widget>
-      </item>
-      <item row="6" column="1" colspan="2">
-       <widget class="QLineEdit" name="lineEdit_setversion">
-        <property name="enabled">
-         <bool>false</bool>
-        </property>
-       </widget>
-      </item>
-      <item row="5" column="1" colspan="2">
-       <widget class="QLineEdit" name="lineEdit_setproid">
-        <property name="enabled">
-         <bool>false</bool>
-        </property>
-       </widget>
-      </item>
-      <item row="1" column="1">
-       <widget class="QPushButton" name="pushButton_education">
-        <property name="text">
-         <string>鎺堟潈鏁欒偛鐗�</string>
-        </property>
-       </widget>
-      </item>
-      <item row="0" column="2">
-       <widget class="QPushButton" name="pushButton">
-        <property name="text">
-         <string>璇︾粏淇℃伅&gt;&gt;</string>
-        </property>
-       </widget>
-      </item>
-      <item row="6" column="0">
-       <widget class="QPushButton" name="pushButton_setversion">
-        <property name="enabled">
-         <bool>false</bool>
-        </property>
-        <property name="text">
-         <string>璁剧疆鐗堟湰</string>
+         <string>+1涓湀</string>
         </property>
        </widget>
       </item>
@@ -222,13 +140,34 @@
         </property>
        </widget>
       </item>
-      <item row="2" column="1">
-       <widget class="QPushButton" name="pushButton_accreditcell">
+      <item row="1" column="0">
+       <widget class="QPushButton" name="pushButton_normal">
+        <property name="text">
+         <string>鎺堟潈鏅�氱増</string>
+        </property>
+       </widget>
+      </item>
+      <item row="5" column="1" colspan="2">
+       <widget class="QLineEdit" name="lineEdit_setproid">
+        <property name="enabled">
+         <bool>false</bool>
+        </property>
+       </widget>
+      </item>
+      <item row="3" column="1">
+       <widget class="QPushButton" name="pushButton_accreditpipe">
         <property name="enabled">
          <bool>false</bool>
         </property>
         <property name="text">
-         <string>鎺堟潈瀛旈殭鍗曞厓</string>
+         <string>鎺堟潈鍗曡闅�</string>
+        </property>
+       </widget>
+      </item>
+      <item row="6" column="1" colspan="2">
+       <widget class="QLineEdit" name="lineEdit_setversion">
+        <property name="enabled">
+         <bool>false</bool>
         </property>
        </widget>
       </item>
@@ -242,13 +181,40 @@
         </property>
        </widget>
       </item>
-      <item row="4" column="0">
-       <widget class="QPushButton" name="pushButton_dateset">
+      <item row="2" column="0">
+       <widget class="QPushButton" name="pushButton_accreditall">
         <property name="enabled">
          <bool>false</bool>
         </property>
         <property name="text">
-         <string>鏃堕棿鍚屾</string>
+         <string>鎺堟潈鎵�鏈夋ā鍧�</string>
+        </property>
+       </widget>
+      </item>
+      <item row="5" column="0">
+       <widget class="QPushButton" name="pushButton_setproid">
+        <property name="enabled">
+         <bool>false</bool>
+        </property>
+        <property name="text">
+         <string>璁剧疆浜у搧鍙�</string>
+        </property>
+       </widget>
+      </item>
+      <item row="6" column="0">
+       <widget class="QPushButton" name="pushButton_setversion">
+        <property name="enabled">
+         <bool>false</bool>
+        </property>
+        <property name="text">
+         <string>璁剧疆鐗堟湰</string>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="2">
+       <widget class="QPushButton" name="pushButton">
+        <property name="text">
+         <string>璇︾粏淇℃伅&gt;&gt;</string>
         </property>
        </widget>
       </item>
@@ -256,6 +222,43 @@
        <widget class="QPushButton" name="pushButton_viewUsers">
         <property name="text">
          <string>鏌ョ湅宸叉縺娲荤敤鎴�</string>
+        </property>
+       </widget>
+      </item>
+      <item row="2" column="2">
+       <widget class="QPushButton" name="pushButton_accreditaquifer">
+        <property name="enabled">
+         <bool>false</bool>
+        </property>
+        <property name="text">
+         <string>鎺堟潈鍚按閫氶亾</string>
+        </property>
+       </widget>
+      </item>
+      <item row="2" column="1">
+       <widget class="QPushButton" name="pushButton_accreditcell">
+        <property name="enabled">
+         <bool>false</bool>
+        </property>
+        <property name="text">
+         <string>鎺堟潈瀛旈殭鍗曞厓</string>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="1">
+       <widget class="QPushButton" name="pushButton_education">
+        <property name="text">
+         <string>鎺堟潈鏁欒偛鐗�</string>
+        </property>
+       </widget>
+      </item>
+      <item row="4" column="0">
+       <widget class="QPushButton" name="pushButton_dateset">
+        <property name="enabled">
+         <bool>false</bool>
+        </property>
+        <property name="text">
+         <string>鏃堕棿鍚屾</string>
         </property>
        </widget>
       </item>
@@ -303,6 +306,9 @@
          </item>
          <item row="0" column="1" rowspan="2" colspan="6">
           <widget class="QTextEdit" name="textEdit_localid">
+           <property name="lineWrapMode">
+            <enum>QTextEdit::WidgetWidth</enum>
+           </property>
            <property name="readOnly">
             <bool>false</bool>
            </property>
diff --git a/shortcrypto.cpp b/shortcrypto.cpp
new file mode 100644
index 0000000..796fcb8
--- /dev/null
+++ b/shortcrypto.cpp
@@ -0,0 +1,200 @@
+锘�#include "shortcrypto.h"
+#include "tinyaes.h"
+#include <QtDebug>
+
+// Base85 瀛楃闆嗭細85涓彲鎵撳嵃瀛楃锛岄伩寮�瀹规槗鍦║RL/JSON閲屽嚭闂鐨勫瓧绗�
+const char *ShortCrypto::BASE85_CHARS =
+    "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~";
+
+namespace {
+    QByteArray pkcs7Pad(const QByteArray &data, int blockSize) {
+        int padLen = blockSize - (data.size() % blockSize);
+        if (padLen == 0) padLen = blockSize;
+        QByteArray result = data;
+        result.append(QByteArray(padLen, static_cast<char>(padLen)));
+        return result;
+    }
+
+    bool isPkcs7Valid(const QByteArray &data, int blockSize = 16) {
+        if (data.isEmpty() || data.size() % blockSize != 0) return false;
+        unsigned char padLen = static_cast<unsigned char>(data.at(data.size() - 1));
+        if (padLen == 0 || padLen > static_cast<unsigned char>(blockSize)) return false;
+        for (int i = 0; i < padLen; ++i)
+            if (static_cast<unsigned char>(data.at(data.size() - 1 - i)) != padLen) return false;
+        return true;
+    }
+
+    QByteArray pkcs7Unpad(const QByteArray &data) {
+        if (data.isEmpty()) return QByteArray();
+        unsigned char padLen = static_cast<unsigned char>(data.at(data.size() - 1));
+        if (padLen == 0 || padLen > 16 || padLen > static_cast<unsigned char>(data.size())) return QByteArray();
+        return data.left(data.size() - padLen);
+    }
+}
+
+QString ShortCrypto::encrypt(const QByteArray &plaintext, const QByteArray &key, const QByteArray &iv)
+{
+    if (key.size() != 16) {
+        qWarning() << "ShortCrypto::encrypt: key must be 16 bytes for AES-128";
+        return QString();
+    }
+
+    QByteArray adjustedIv = iv;
+    if (adjustedIv.isEmpty()) {
+        adjustedIv = QByteArray(16, '\0');  // 榛樿鍏ㄩ浂IV锛堟寮忕幆澧冨缓璁敤闅忔満IV骞堕檮甯﹀湪瀵嗘枃鍓嶏級
+    } else if (adjustedIv.size() != 16) {
+        adjustedIv = adjustedIv.left(16);
+        adjustedIv.append(QByteArray(16 - adjustedIv.size(), '\0'));
+    }
+
+    // 1. PKCS7 濉厖
+    QByteArray padded = pkcs7Pad(plaintext, 16);
+
+    // 2. AES-128-CBC 鍔犲瘑锛堜娇鐢� Tiny-AES-C锛岀函杞欢瀹炵幇锛屾棤 MSVC 鍏煎鎬ч棶棰橈級
+    QByteArray encrypted = padded;
+    struct AES_ctx ctx;
+    AES_init_ctx_iv(&ctx, reinterpret_cast<const uint8_t*>(key.constData()),
+                    reinterpret_cast<const uint8_t*>(adjustedIv.constData()));
+    AES_CBC_encrypt_buffer(&ctx, reinterpret_cast<uint8_t*>(encrypted.data()), encrypted.size());
+
+    // 3. Base85 缂栫爜锛岀缉鐭瓧绗︽暟
+    QByteArray encoded = base85Encode(encrypted);
+    return QString::fromLatin1(encoded);
+}
+
+QByteArray ShortCrypto::decrypt(const QString &ciphertext, const QByteArray &key, const QByteArray &iv)
+{
+    if (key.size() != 16) {
+        qWarning() << "ShortCrypto::decrypt: key must be 16 bytes for AES-128";
+        return QByteArray();
+    }
+
+    QByteArray adjustedIv = iv;
+    if (adjustedIv.isEmpty()) {
+        adjustedIv = QByteArray(16, '\0');
+    } else if (adjustedIv.size() != 16) {
+        adjustedIv = adjustedIv.left(16);
+        adjustedIv.append(QByteArray(16 - adjustedIv.size(), '\0'));
+    }
+
+    // 1. Base85 瑙g爜
+    QByteArray encrypted = base85Decode(ciphertext);
+    if (encrypted.isEmpty()) {
+        qWarning() << "ShortCrypto::decrypt: base85 decode failed";
+        return QByteArray();
+    }
+
+    if (encrypted.size() % 16 != 0) {
+        qWarning() << "ShortCrypto::decrypt: decoded data size not aligned to block size:" << encrypted.size();
+        return QByteArray();
+    }
+
+    // 2. AES-128-CBC 瑙e瘑
+    QByteArray decrypted = encrypted;
+    struct AES_ctx ctx;
+    AES_init_ctx_iv(&ctx, reinterpret_cast<const uint8_t*>(key.constData()),
+                    reinterpret_cast<const uint8_t*>(adjustedIv.constData()));
+    AES_CBC_decrypt_buffer(&ctx, reinterpret_cast<uint8_t*>(decrypted.data()), decrypted.size());
+
+    // 3. PKCS7 楠岃瘉鍜岀Щ闄ゅ~鍏�
+    if (!isPkcs7Valid(decrypted)) {
+        qWarning() << "ShortCrypto::decrypt: PKCS7 validation failed, wrong key or corrupted data";
+        return QByteArray();
+    }
+
+    return pkcs7Unpad(decrypted);
+}
+
+QByteArray ShortCrypto::base85Encode(const QByteArray &data)
+{
+    QByteArray result;
+    result.reserve((data.size() + 3) / 4 * 5);
+
+    const unsigned char *ptr = reinterpret_cast<const unsigned char *>(data.constData());
+    int len = data.size();
+
+    while (len >= 4) {
+        quint32 val = (quint32(ptr[0]) << 24) | (quint32(ptr[1]) << 16) |
+                      (quint32(ptr[2]) << 8) | quint32(ptr[3]);
+        char buf[5];
+        for (int i = 4; i >= 0; --i) {
+            buf[i] = BASE85_CHARS[val % 85];
+            val /= 85;
+        }
+        result.append(buf, 5);
+        ptr += 4;
+        len -= 4;
+    }
+
+    // 澶勭悊鍓╀綑瀛楄妭锛�1~3瀛楄妭锛�
+    if (len > 0) {
+        quint32 val = 0;
+        for (int i = 0; i < len; ++i) {
+            val |= (quint32(ptr[i]) << (24 - i * 8));
+        }
+        char buf[5];
+        for (int i = 4; i >= 0; --i) {
+            buf[i] = BASE85_CHARS[val % 85];
+            val /= 85;
+        }
+        result.append(buf, len + 1);  // n瀛楄妭闇�瑕乶+1涓瓧绗﹁〃绀�
+    }
+
+    return result;
+}
+
+QByteArray ShortCrypto::base85Decode(const QString &text)
+{
+    QByteArray input = text.toLatin1();
+    QByteArray result;
+    result.reserve(input.size() / 5 * 4);
+
+    // 鏋勫缓鍙嶅悜鏌ユ壘琛�
+    int charToVal[256];
+    memset(charToVal, -1, sizeof(charToVal));
+    for (int i = 0; i < 85; ++i) {
+        charToVal[static_cast<unsigned char>(BASE85_CHARS[i])] = i;
+    }
+
+    const unsigned char *ptr = reinterpret_cast<const unsigned char *>(input.constData());
+    int len = input.size();
+    int pos = 0;
+
+    while (pos < len) {
+        // 璇诲彇涓�涓�5瀛楃鍧楋紙鎴栨湯灏剧殑鐭潡锛�
+        int chunkLen = qMin(5, len - pos);
+        quint32 val = 0;
+        for (int i = 0; i < chunkLen; ++i) {
+            int v = charToVal[ptr[pos + i]];
+            if (v < 0) {
+                qWarning() << "ShortCrypto::base85Decode: invalid character:" << QChar(ptr[pos + i]);
+                return QByteArray();
+            }
+            val = val * 85 + v;
+        }
+
+        if (chunkLen == 5) {
+            result.append(static_cast<char>((val >> 24) & 0xFF));
+            result.append(static_cast<char>((val >> 16) & 0xFF));
+            result.append(static_cast<char>((val >> 8) & 0xFF));
+            result.append(static_cast<char>(val & 0xFF));
+        } else {
+            // 鏈熬鐭潡锛氱敤 'u'(84) 濉厖鍒� 5 涓瓧绗︼紝鍐嶈В鐮�
+            for (int i = chunkLen; i < 5; ++i)
+                val = val * 85 + 84;
+
+            char out[4];
+            out[0] = static_cast<char>((val >> 24) & 0xFF);
+            out[1] = static_cast<char>((val >> 16) & 0xFF);
+            out[2] = static_cast<char>((val >> 8) & 0xFF);
+            out[3] = static_cast<char>(val & 0xFF);
+
+            int outBytes = chunkLen - 1;
+            for (int i = 0; i < outBytes; ++i)
+                result.append(out[i]);
+        }
+        pos += chunkLen;
+    }
+
+    return result;
+}
diff --git a/shortcrypto.h b/shortcrypto.h
new file mode 100644
index 0000000..9f0756e
--- /dev/null
+++ b/shortcrypto.h
@@ -0,0 +1,40 @@
+锘�#ifndef SHORTCRYPTO_H
+#define SHORTCRYPTO_H
+
+#include <QByteArray>
+#include <QString>
+
+/**
+ * @brief 鏈�鐭瘑鏂囧姞瀵嗗伐鍏风被
+ * 娴佺▼锛氭槑鏂� 鈫� PKCS7濉厖 鈫� AES-128-CBC鍔犲瘑 鈫� Base85缂栫爜
+ */
+class ShortCrypto
+{
+public:
+    /**
+     * @brief 鍔犲瘑
+     * @param plaintext 鍘熷鏄庢枃
+     * @param key 16瀛楄妭瀵嗛挜锛圓ES-128锛�
+     * @param iv 16瀛楄妭鍒濆鍚戦噺锛屽彲涓虹┖锛堝唴閮ㄨ嚜鍔ㄨˉ闆讹級
+     * @return Base85缂栫爜鐨勫瘑鏂囧瓧绗︿覆
+     */
+    static QString encrypt(const QByteArray &plaintext, const QByteArray &key, const QByteArray &iv = QByteArray());
+
+    /**
+     * @brief 瑙e瘑
+     * @param ciphertext Base85缂栫爜鐨勫瘑鏂�
+     * @param key 16瀛楄妭瀵嗛挜锛圓ES-128锛�
+     * @param iv 16瀛楄妭鍒濆鍚戦噺锛屽繀椤讳笌鍔犲瘑鏃朵竴鑷�
+     * @return 鍘熷鏄庢枃
+     */
+    static QByteArray decrypt(const QString &ciphertext, const QByteArray &key, const QByteArray &iv = QByteArray());
+
+private:
+    // Base85 瀛楃闆嗭紙RFC 1924 鍙樹綋锛屼笉鍚紩鍙�/閫楀彿/鍙ョ偣/鏂滄潬锛岄伩鍏岼SON/XML杞箟闂锛�
+    static const char *BASE85_CHARS;
+
+    static QByteArray base85Encode(const QByteArray &data);
+    static QByteArray base85Decode(const QString &text);
+};
+
+#endif // SHORTCRYPTO_H
diff --git a/tinyaes.cpp b/tinyaes.cpp
new file mode 100644
index 0000000..c2d0e1a
--- /dev/null
+++ b/tinyaes.cpp
@@ -0,0 +1,264 @@
+#include "tinyaes.h"
+#include <string.h>
+
+#define Nb 4
+#define Nk 4
+#define Nr 10
+
+typedef uint8_t state_t[4][4];
+
+static const uint8_t sbox[256] = {
+    0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5,0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76,
+    0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0,0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0,
+    0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc,0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15,
+    0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a,0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75,
+    0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0,0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84,
+    0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b,0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf,
+    0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85,0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8,
+    0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5,0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2,
+    0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17,0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73,
+    0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88,0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb,
+    0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c,0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79,
+    0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9,0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08,
+    0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6,0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a,
+    0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e,0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e,
+    0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94,0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf,
+    0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68,0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16
+};
+
+static const uint8_t rsbox[256] = {
+    0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38,0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb,
+    0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87,0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb,
+    0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d,0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e,
+    0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2,0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25,
+    0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16,0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92,
+    0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda,0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84,
+    0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a,0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06,
+    0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02,0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b,
+    0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea,0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73,
+    0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85,0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e,
+    0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89,0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b,
+    0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20,0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4,
+    0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31,0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f,
+    0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d,0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef,
+    0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0,0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61,
+    0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26,0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d
+};
+
+static const uint8_t Rcon[11] = {
+    0x8d,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x1b,0x36
+};
+
+#define getSBoxValue(num) (sbox[(num)])
+
+static void KeyExpansion(uint8_t* RoundKey, const uint8_t* Key)
+{
+    unsigned i, j, k;
+    uint8_t tempa[4];
+    for (i = 0; i < Nk; ++i) {
+        RoundKey[(i * 4) + 0] = Key[(i * 4) + 0];
+        RoundKey[(i * 4) + 1] = Key[(i * 4) + 1];
+        RoundKey[(i * 4) + 2] = Key[(i * 4) + 2];
+        RoundKey[(i * 4) + 3] = Key[(i * 4) + 3];
+    }
+    for (i = Nk; i < Nb * (Nr + 1); ++i) {
+        k = (i - 1) * 4;
+        tempa[0]=RoundKey[k + 0];
+        tempa[1]=RoundKey[k + 1];
+        tempa[2]=RoundKey[k + 2];
+        tempa[3]=RoundKey[k + 3];
+        if (i % Nk == 0) {
+            const uint8_t u8tmp = tempa[0];
+            tempa[0] = tempa[1];
+            tempa[1] = tempa[2];
+            tempa[2] = tempa[3];
+            tempa[3] = u8tmp;
+            tempa[0] = getSBoxValue(tempa[0]);
+            tempa[1] = getSBoxValue(tempa[1]);
+            tempa[2] = getSBoxValue(tempa[2]);
+            tempa[3] = getSBoxValue(tempa[3]);
+            tempa[0] = tempa[0] ^ Rcon[i/Nk];
+        }
+        j = i * 4; k=(i - Nk) * 4;
+        RoundKey[j + 0] = RoundKey[k + 0] ^ tempa[0];
+        RoundKey[j + 1] = RoundKey[k + 1] ^ tempa[1];
+        RoundKey[j + 2] = RoundKey[k + 2] ^ tempa[2];
+        RoundKey[j + 3] = RoundKey[k + 3] ^ tempa[3];
+    }
+}
+
+void AES_init_ctx_iv(struct AES_ctx* ctx, const uint8_t* key, const uint8_t* iv)
+{
+    KeyExpansion(ctx->RoundKey, key);
+    memcpy(ctx->Iv, iv, AES_BLOCKLEN);
+}
+
+static void AddRoundKey(uint8_t round, state_t* state, const uint8_t* RoundKey)
+{
+    uint8_t i,j;
+    for (i = 0; i < 4; ++i)
+        for (j = 0; j < 4; ++j)
+            (*state)[i][j] ^= RoundKey[(round * Nb * 4) + (i * Nb) + j];
+}
+
+static void SubBytes(state_t* state)
+{
+    uint8_t i, j;
+    for (i = 0; i < 4; ++i)
+        for (j = 0; j < 4; ++j)
+            (*state)[j][i] = getSBoxValue((*state)[j][i]);
+}
+
+static void ShiftRows(state_t* state)
+{
+    uint8_t temp;
+    temp           = (*state)[0][1];
+    (*state)[0][1] = (*state)[1][1];
+    (*state)[1][1] = (*state)[2][1];
+    (*state)[2][1] = (*state)[3][1];
+    (*state)[3][1] = temp;
+    temp           = (*state)[0][2];
+    (*state)[0][2] = (*state)[2][2];
+    (*state)[2][2] = temp;
+    temp           = (*state)[1][2];
+    (*state)[1][2] = (*state)[3][2];
+    (*state)[3][2] = temp;
+    temp           = (*state)[0][3];
+    (*state)[0][3] = (*state)[3][3];
+    (*state)[3][3] = (*state)[2][3];
+    (*state)[2][3] = (*state)[1][3];
+    (*state)[1][3] = temp;
+}
+
+static uint8_t xtime(uint8_t x)
+{
+    return ((x<<1) ^ (((x>>7) & 1) * 0x1b));
+}
+
+static void MixColumns(state_t* state)
+{
+    uint8_t i;
+    uint8_t Tmp, Tm, t;
+    for (i = 0; i < 4; ++i) {
+        t   = (*state)[i][0];
+        Tmp = (*state)[i][0] ^ (*state)[i][1] ^ (*state)[i][2] ^ (*state)[i][3];
+        Tm  = (*state)[i][0] ^ (*state)[i][1]; Tm = xtime(Tm);  (*state)[i][0] ^= Tm ^ Tmp;
+        Tm  = (*state)[i][1] ^ (*state)[i][2]; Tm = xtime(Tm);  (*state)[i][1] ^= Tm ^ Tmp;
+        Tm  = (*state)[i][2] ^ (*state)[i][3]; Tm = xtime(Tm);  (*state)[i][2] ^= Tm ^ Tmp;
+        Tm  = (*state)[i][3] ^ t;              Tm = xtime(Tm);  (*state)[i][3] ^= Tm ^ Tmp;
+    }
+}
+
+static uint8_t Multiply(uint8_t x, uint8_t y)
+{
+    return (((y & 1) * x) ^
+           ((y>>1 & 1) * xtime(x)) ^
+           ((y>>2 & 1) * xtime(xtime(x))) ^
+           ((y>>3 & 1) * xtime(xtime(xtime(x)))) ^
+           ((y>>4 & 1) * xtime(xtime(xtime(xtime(x))))));
+}
+
+static void InvMixColumns(state_t* state)
+{
+    int i;
+    uint8_t a, b, c, d;
+    for (i = 0; i < 4; ++i) {
+        a = (*state)[i][0];
+        b = (*state)[i][1];
+        c = (*state)[i][2];
+        d = (*state)[i][3];
+        (*state)[i][0] = Multiply(a, 0x0e) ^ Multiply(b, 0x0b) ^ Multiply(c, 0x0d) ^ Multiply(d, 0x09);
+        (*state)[i][1] = Multiply(a, 0x09) ^ Multiply(b, 0x0e) ^ Multiply(c, 0x0b) ^ Multiply(d, 0x0d);
+        (*state)[i][2] = Multiply(a, 0x0d) ^ Multiply(b, 0x09) ^ Multiply(c, 0x0e) ^ Multiply(d, 0x0b);
+        (*state)[i][3] = Multiply(a, 0x0b) ^ Multiply(b, 0x0d) ^ Multiply(c, 0x09) ^ Multiply(d, 0x0e);
+    }
+}
+
+static void InvSubBytes(state_t* state)
+{
+    uint8_t i, j;
+    for (i = 0; i < 4; ++i)
+        for (j = 0; j < 4; ++j)
+            (*state)[j][i] = rsbox[(*state)[j][i]];
+}
+
+static void InvShiftRows(state_t* state)
+{
+    uint8_t temp;
+    temp = (*state)[3][1];
+    (*state)[3][1] = (*state)[2][1];
+    (*state)[2][1] = (*state)[1][1];
+    (*state)[1][1] = (*state)[0][1];
+    (*state)[0][1] = temp;
+    temp = (*state)[0][2];
+    (*state)[0][2] = (*state)[2][2];
+    (*state)[2][2] = temp;
+    temp = (*state)[1][2];
+    (*state)[1][2] = (*state)[3][2];
+    (*state)[3][2] = temp;
+    temp = (*state)[0][3];
+    (*state)[0][3] = (*state)[1][3];
+    (*state)[1][3] = (*state)[2][3];
+    (*state)[2][3] = (*state)[3][3];
+    (*state)[3][3] = temp;
+}
+
+static void Cipher(state_t* state, const uint8_t* RoundKey)
+{
+    uint8_t round = 0;
+    AddRoundKey(0, state, RoundKey);
+    for (round = 1; ; ++round) {
+        SubBytes(state);
+        ShiftRows(state);
+        if (round == Nr) break;
+        MixColumns(state);
+        AddRoundKey(round, state, RoundKey);
+    }
+    AddRoundKey(Nr, state, RoundKey);
+}
+
+static void InvCipher(state_t* state, const uint8_t* RoundKey)
+{
+    uint8_t round = 0;
+    AddRoundKey(Nr, state, RoundKey);
+    for (round = (Nr - 1); ; --round) {
+        InvShiftRows(state);
+        InvSubBytes(state);
+        AddRoundKey(round, state, RoundKey);
+        if (round == 0) break;
+        InvMixColumns(state);
+    }
+}
+
+static void XorWithIv(uint8_t* buf, const uint8_t* Iv)
+{
+    uint8_t i;
+    for (i = 0; i < AES_BLOCKLEN; ++i)
+        buf[i] ^= Iv[i];
+}
+
+void AES_CBC_encrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length)
+{
+    size_t i;
+    uint8_t* Iv = ctx->Iv;
+    for (i = 0; i < length; i += AES_BLOCKLEN) {
+        XorWithIv(buf, Iv);
+        Cipher((state_t*)buf, ctx->RoundKey);
+        Iv = buf;
+        buf += AES_BLOCKLEN;
+    }
+    memcpy(ctx->Iv, Iv, AES_BLOCKLEN);
+}
+
+void AES_CBC_decrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length)
+{
+    size_t i;
+    uint8_t storeNextIv[AES_BLOCKLEN];
+    for (i = 0; i < length; i += AES_BLOCKLEN) {
+        memcpy(storeNextIv, buf, AES_BLOCKLEN);
+        InvCipher((state_t*)buf, ctx->RoundKey);
+        XorWithIv(buf, ctx->Iv);
+        memcpy(ctx->Iv, storeNextIv, AES_BLOCKLEN);
+        buf += AES_BLOCKLEN;
+    }
+}
diff --git a/tinyaes.h b/tinyaes.h
new file mode 100644
index 0000000..088ffa4
--- /dev/null
+++ b/tinyaes.h
@@ -0,0 +1,21 @@
+#ifndef TINYAES_H
+#define TINYAES_H
+
+#include <stdint.h>
+#include <stddef.h>
+
+#define AES_BLOCKLEN 16
+#define AES_KEYLEN 16
+#define AES_keyExpSize 176
+
+struct AES_ctx
+{
+    uint8_t RoundKey[AES_keyExpSize];
+    uint8_t Iv[AES_BLOCKLEN];
+};
+
+void AES_init_ctx_iv(struct AES_ctx* ctx, const uint8_t* key, const uint8_t* iv);
+void AES_CBC_encrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length);
+void AES_CBC_decrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length);
+
+#endif // TINYAES_H

--
Gitblit v1.9.1