From a715f9c49f732908691341951b1643f7b8fae91b Mon Sep 17 00:00:00 2001
From: ccy <3140717620@qq.com>
Date: 星期五, 23 十月 2026 14:48:42 +0800
Subject: [PATCH] 将加密字符修改为全部是英文大小写,去掉之前奇怪的标识符号

---
 shortcrypto.cpp |  189 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 184 insertions(+), 5 deletions(-)

diff --git a/shortcrypto.cpp b/shortcrypto.cpp
index 796fcb8..f373ba2 100644
--- a/shortcrypto.cpp
+++ b/shortcrypto.cpp
@@ -1,10 +1,20 @@
 锘�#include "shortcrypto.h"
 #include "tinyaes.h"
 #include <QtDebug>
+#include <QtMath>
+#include <algorithm>
 
 // Base85 瀛楃闆嗭細85涓彲鎵撳嵃瀛楃锛岄伩寮�瀹规槗鍦║RL/JSON閲屽嚭闂鐨勫瓧绗�
 const char *ShortCrypto::BASE85_CHARS =
     "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~";
+
+// V3 瀛楃闆嗭細绾ぇ鍐欏瓧姣嶏紙26瀛楃锛夛紝璁稿彲瀵嗛挜鍙惈 A-Z锛�28浣�
+const char *ShortCrypto::V3_CHARS =
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+// V2 瀛楃闆嗭細澶у皬鍐欏瓧姣嶏紙52瀛楃锛夛紝璁惧ID鍙惈瀛楁瘝銆佷笉鍚暟瀛椾笌鐗规畩瀛楃
+const char *ShortCrypto::BASE52_CHARS =
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
 
 namespace {
     QByteArray pkcs7Pad(const QByteArray &data, int blockSize) {
@@ -57,8 +67,8 @@
                     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);
+    // 3. 绾瓧姣嶇紪鐮侊紙52瀛楃闆嗭級锛�48瀛楄妭瀵嗘枃 鈫� 68瀛楃
+    QByteArray encoded = baseNEncode(encrypted, BASE52_CHARS, 52);
     return QString::fromLatin1(encoded);
 }
 
@@ -77,10 +87,18 @@
         adjustedIv.append(QByteArray(16 - adjustedIv.size(), '\0'));
     }
 
-    // 1. Base85 瑙g爜
-    QByteArray encrypted = base85Decode(ciphertext);
+    // 1. 浼樺厛鎸夌函瀛楁瘝琛紙52瀛楃闆嗭級瑙g爜锛�52^瀛楃鏁� 涓� 256瀛楄妭鐣� 鐨勫ご绌洪棿涓嶈冻1瀛楄妭锛�
+    //    鐪熷�艰嚦澶氫涪澶�1涓墠瀵奸浂瀛楄妭锛岄暱搴︿笉瀵归綈鏃惰ˉ鍥�
+    QByteArray encrypted = baseNDecodeVar(ciphertext, BASE52_CHARS, 52);
+    if (!encrypted.isEmpty() && encrypted.size() % 16 != 0) {
+        encrypted.prepend('\0');
+    }
+    if (encrypted.isEmpty() || encrypted.size() % 16 != 0) {
+        // 鍥為��锛氭棭鏈烞ase85鐗堝瘑鏂�
+        encrypted = base85Decode(ciphertext);
+    }
     if (encrypted.isEmpty()) {
-        qWarning() << "ShortCrypto::decrypt: base85 decode failed";
+        qWarning() << "ShortCrypto::decrypt: decode failed";
         return QByteArray();
     }
 
@@ -105,6 +123,167 @@
     return pkcs7Unpad(decrypted);
 }
 
+QString ShortCrypto::encryptRaw(const QByteArray &plaintext, const QByteArray &key)
+{
+    if (key.size() != 16) {
+        qWarning() << "ShortCrypto::encryptRaw: key must be 16 bytes for AES-128";
+        return QString();
+    }
+    if (plaintext.isEmpty() || plaintext.size() % 16 != 0) {
+        qWarning() << "ShortCrypto::encryptRaw: plaintext size must be a non-zero multiple of 16, got"
+                   << plaintext.size();
+        return QString();
+    }
+
+    // 鍗曞潡鏃跺叏闆禝V鐨凜BC绛変环浜嶦CB锛涘鍧楁椂涓篊BC閾炬帴
+    QByteArray adjustedIv(16, '\0');
+
+    QByteArray encrypted = plaintext;
+    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());
+
+    // 绾ぇ鍐欏瓧姣嶇紪鐮侊細16瀛楄妭瀵嗘枃 鈫� 28瀛楃锛堣嫢鍏佽鏁板瓧鎹�36瀛楃闆嗭紝闀垮害闄嶅埌25锛�
+    QByteArray encoded = baseNEncode(encrypted, V3_CHARS, 26);
+    return QString::fromLatin1(encoded);
+}
+
+QByteArray ShortCrypto::decryptRaw(const QString &ciphertext, const QByteArray &key)
+{
+    if (key.size() != 16) {
+        qWarning() << "ShortCrypto::decryptRaw: key must be 16 bytes for AES-128";
+        return QByteArray();
+    }
+
+    // 浼樺厛鎸夌函瀛楁瘝琛ㄨВ鐮侊紱鑻ュ惈琛ㄥ瀛楃锛堟棭鏈烞ase85鐗圴3瀵嗛挜锛夊垯鍥為��Base85
+    QByteArray encrypted = baseNDecode(ciphertext, V3_CHARS, 26);
+    if (encrypted.isEmpty()) {
+        encrypted = base85Decode(ciphertext);
+    }
+    if (encrypted.isEmpty()) {
+        qWarning() << "ShortCrypto::decryptRaw: decode failed";
+        return QByteArray();
+    }
+    if (encrypted.size() % 16 != 0) {
+        qWarning() << "ShortCrypto::decryptRaw: decoded data size not aligned to block size:"
+                   << encrypted.size();
+        return QByteArray();
+    }
+
+    QByteArray adjustedIv(16, '\0');
+    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());
+    return decrypted;
+}
+
+QByteArray ShortCrypto::baseNEncode(const QByteArray &data, const char *alphabet, int base)
+{
+    // 鎶婃暣娈靛ぇ绔瓧鑺傚簭褰撲綔涓�涓ぇ鏁存暟锛岄�愭闄や互base鍙栦綑鏁�
+    QByteArray num = data;
+    QByteArray remainders;
+
+    bool isZero = false;
+    while (!isZero) {
+        isZero = true;
+        unsigned int carry = 0;
+        for (int i = 0; i < num.size(); ++i) {
+            unsigned int cur = (carry << 8) | static_cast<unsigned char>(num.at(i));
+            num[i] = static_cast<char>(cur / static_cast<unsigned int>(base));
+            carry = cur % static_cast<unsigned int>(base);
+            if (num.at(i) != 0) isZero = false;
+        }
+        if (isZero && remainders.isEmpty()) break; // 鍏ㄩ浂杈撳叆
+        remainders.append(alphabet[static_cast<int>(carry)]);
+        if (isZero) break;
+    }
+    if (remainders.isEmpty()) remainders.append(alphabet[0]);
+
+    // 杩樺師涓洪珮浣嶅湪鍓嶏紝骞剁敤alphabet[0]琛ラ綈鍥哄畾浣嶆暟锛堝墠瀵奸浂锛�
+    QByteArray result = remainders;
+    std::reverse(result.begin(), result.end());
+    int minimalLen = static_cast<int>(qCeil(data.size() * 8.0 * qLn(2.0) / qLn(static_cast<double>(base))));
+    if (result.size() < minimalLen) {
+        result.prepend(QByteArray(minimalLen - result.size(), alphabet[0]));
+    }
+    return result;
+}
+
+QByteArray ShortCrypto::baseNDecode(const QString &text, const char *alphabet, int base)
+{
+    // 寤虹珛瀛楃绱㈠紩琛�
+    int charToVal[256];
+    memset(charToVal, -1, sizeof(charToVal));
+    for (int i = 0; i < base; ++i) {
+        charToVal[static_cast<unsigned char>(alphabet[i])] = i;
+    }
+
+    // Horner娉曞垯锛歯um = num * base + v锛堝ぇ绔瓧鑺傚簭锛�
+    QByteArray num(16, '\0');
+    QByteArray input = text.toLatin1();
+    for (int i = 0; i < input.size(); ++i) {
+        int v = charToVal[static_cast<unsigned char>(input.at(i))];
+        if (v < 0) {
+            qWarning() << "ShortCrypto::baseNDecode: invalid character:" << QChar(input.at(i));
+            return QByteArray();
+        }
+        unsigned int carry = static_cast<unsigned int>(v);
+        for (int b = num.size() - 1; b >= 0; --b) {
+            unsigned int cur = (static_cast<unsigned int>(static_cast<unsigned char>(num.at(b))) * static_cast<unsigned int>(base)) + carry;
+            num[b] = static_cast<char>(cur & 0xFF);
+            carry = cur >> 8;
+        }
+        if (carry != 0) {
+            qWarning() << "ShortCrypto::baseNDecode: value overflows 128 bits";
+            return QByteArray();
+        }
+    }
+
+    // 淇濇寔16瀛楄妭瀹氬锛堝墠瀵奸浂鏈夋剰涔夛級锛岃皟鐢ㄦ柟鎸夊浐瀹氬潡闀垮鐞�
+    return num;
+}
+
+QByteArray ShortCrypto::baseNDecodeVar(const QString &text, const char *alphabet, int base)
+{
+    // 寤虹珛瀛楃绱㈠紩琛�
+    int charToVal[256];
+    memset(charToVal, -1, sizeof(charToVal));
+    for (int i = 0; i < base; ++i) {
+        charToVal[static_cast<unsigned char>(alphabet[i])] = i;
+    }
+
+    // 灏忕鍔ㄦ�佸瓧鑺傛暟缁勬墽琛� Horner锛歯um = num * base + v
+    // num[0] 涓烘渶浣庡瓧鑺傦紝杩涗綅鍚戝熬閮紙楂樹綅锛変紶鎾�
+    QByteArray num(1, '\0');
+    QByteArray input = text.toLatin1();
+    for (int i = 0; i < input.size(); ++i) {
+        int v = charToVal[static_cast<unsigned char>(input.at(i))];
+        if (v < 0) {
+            qWarning() << "ShortCrypto::baseNDecodeVar: invalid character:" << QChar(input.at(i));
+            return QByteArray();
+        }
+        unsigned int carry = static_cast<unsigned int>(v);
+        for (int b = 0; b < num.size(); ++b) {
+            unsigned int cur = (static_cast<unsigned int>(static_cast<unsigned char>(num.at(b))) * static_cast<unsigned int>(base)) + carry;
+            num[b] = static_cast<char>(cur & 0xFF);
+            carry = cur >> 8;
+        }
+        while (carry != 0) {
+            num.append(static_cast<char>(carry & 0xFF));
+            carry >>= 8;
+        }
+    }
+
+    // 杞ぇ绔苟鍘绘帀鍓嶅闆讹紙鍙橀暱妯″紡涓嬪墠瀵奸浂鐨勭湡瀹炰釜鏁扮敱璋冪敤鏂硅ˉ榻愯鍒欐仮澶嶏級
+    std::reverse(num.begin(), num.end());
+    int firstNonZero = 0;
+    while (firstNonZero < num.size() - 1 && num.at(firstNonZero) == 0) ++firstNonZero;
+    return num.mid(firstNonZero);
+}
+
 QByteArray ShortCrypto::base85Encode(const QByteArray &data)
 {
     QByteArray result;

--
Gitblit v1.9.1