From 5e1e4a4b57e298806dba97175fa1fbd5c771c7cd Mon Sep 17 00:00:00 2001
From: ccy <3140717620@qq.com>
Date: 星期五, 09 十月 2026 16:17:18 +0800
Subject: [PATCH] 新的加密方式

---
 licensedata.cpp |  112 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 112 insertions(+), 0 deletions(-)

diff --git a/licensedata.cpp b/licensedata.cpp
index 26d5d1b..fa31615 100644
--- a/licensedata.cpp
+++ b/licensedata.cpp
@@ -1,5 +1,7 @@
 锘�#include "licensedata.h"
 #include <QDataStream>
+#include <QCryptographicHash>
+#include <QRandomGenerator>
 #include <QtDebug>
 
 LicenseData::LicenseData()
@@ -105,6 +107,116 @@
         .arg(activeState);
 }
 
+// ===== V3 绱у噾鏍煎紡锛�20浣嶈鍙瘑閽ョ敤锛�=====
+
+QByteArray LicenseData::machineFingerprint(const QByteArray &uuid, const QByteArray &cpu, const QByteArray &key)
+{
+    // 涓巘oBinary鐩稿悓鐨勫畾闀胯鏁达紝淇濊瘉鎺堟潈绔拰楠岃瘉绔鍚屼竴鍙版満鍣ㄧ畻鍑哄悓涓�鎸囩汗
+    QByteArray u = uuid.left(16);
+    u.append(QByteArray(16 - u.size(), '\0'));
+    QByteArray c = cpu.left(8);
+    c.append(QByteArray(8 - c.size(), '\0'));
+
+    QCryptographicHash hash(QCryptographicHash::Sha256);
+    hash.addData(key);
+    hash.addData(u);
+    hash.addData(c);
+    return hash.result().left(8);
+}
+
+quint16 LicenseData::crc16(const QByteArray &data)
+{
+    // CRC16-CCITT (0xFFFF 鍒濆�硷紝0x1021 澶氶」寮�)
+    quint16 crc = 0xFFFF;
+    for (int i = 0; i < data.size(); ++i) {
+        crc ^= static_cast<quint16>(static_cast<unsigned char>(data.at(i))) << 8;
+        for (int b = 0; b < 8; ++b) {
+            crc = (crc & 0x8000) ? static_cast<quint16>((crc << 1) ^ 0x1021)
+                                 : static_cast<quint16>(crc << 1);
+        }
+    }
+    return crc;
+}
+
+QByteArray LicenseData::toBinaryV3(const QByteArray &key) const
+{
+    QByteArray data(16, '\0');
+
+    // [0..7] 鏈哄櫒鎸囩汗
+    QByteArray fp = machineFingerprint(boardUuid, cpuSerial, key);
+    memcpy(data.data(), fp.constData(), 8);
+
+    // [8..9] 澶辨晥鏃ユ湡锛堜笌V2鍚屼竴2000-01-01鍩哄噯锛�
+    quint16 days = dateToDays(expireDate);
+    data[8]  = static_cast<char>((days >> 8) & 0xFF);
+    data[9]  = static_cast<char>(days & 0xFF);
+
+    // [10] 浜у搧鍙�
+    data[10] = static_cast<char>(productId);
+
+    // [11] 鐗堟湰锛氶珮4浣嶄富鐗堟湰 | 浣�4浣嶆鐗堟湰
+    data[11] = static_cast<char>(((verMajor & 0x0F) << 4) | (verMinor & 0x0F));
+
+    // [12] 鏍囧織锛氶珮4浣嶆牸寮忕増鏈�(1)锛屼綆4浣嶆縺娲荤姸鎬�
+    data[12] = static_cast<char>(0x10 | (activeState & 0x0F));
+
+    // [13..14] CRC16锛堣鐩朳0..12]锛岄殢鏈虹洂涓嶅弬涓庯級
+    quint16 crc = crc16(data.left(13));
+    data[13] = static_cast<char>((crc >> 8) & 0xFF);
+    data[14] = static_cast<char>(crc & 0xFF);
+
+    // [15] 闅忔満鐩�
+    data[15] = static_cast<char>(QRandomGenerator::global()->generate() & 0xFF);
+
+    return data;
+}
+
+bool LicenseData::fromBinaryV3(const QByteArray &data)
+{
+    if (data.size() != 16) {
+        return false;
+    }
+
+    quint8 flags = static_cast<quint8>(data.at(12));
+    if ((flags >> 4) != 0x01) {
+        qWarning() << "LicenseData::fromBinaryV3: not a V3 payload, format version ="
+                   << (flags >> 4);
+        return false;
+    }
+
+    quint16 expectCrc = static_cast<quint16>((static_cast<quint8>(data.at(13)) << 8)
+                                             | static_cast<quint8>(data.at(14)));
+    if (crc16(data.left(13)) != expectCrc) {
+        qWarning() << "LicenseData::fromBinaryV3: CRC check failed, wrong key or corrupted data";
+        return false;
+    }
+
+    machineFp = data.left(8);
+
+    quint16 days = static_cast<quint16>((static_cast<quint8>(data.at(8)) << 8)
+                                        | static_cast<quint8>(data.at(9)));
+    expireDate = daysToDate(days);
+
+    productId = static_cast<quint8>(data.at(10));
+
+    quint8 ver = static_cast<quint8>(data.at(11));
+    verMajor = ver >> 4;
+    verMinor = ver & 0x0F;
+
+    activeState = flags & 0x0F;
+    return true;
+}
+
+QString LicenseData::toDebugStringV3() const
+{
+    return QString("{FP:%1, Expire:%2, Prod:%3, Ver:%4.%5, State:%6}")
+        .arg(binaryToHexString(machineFp))
+        .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);

--
Gitblit v1.9.1