我正在开发一个基于 Qt 的文本编辑器,并尝试解码以 UTF-7 编码的文本。但是,我遇到了解码字符不正确的问题。例如,解码文本 Hello, +Z1TA-(Hello, 世界的 UTF-7 表示形式)会生成 Hello, ᙎ䱵。
我已经在类 InterpreteAsUtf7 中实现了解码逻辑,但我处理 Base64 段或将它们转换为 UTF-16 的方式似乎存在问题。
这是一个演示该问题的简单应用程序。硬编码的 UTF-7 编码字符串(“Hello,+Z1TA-”)应该解码为“Hello,世界”,但事实并非如此。有人可以帮忙确定解码逻辑有什么问题吗?
#include <QString>
#include <QByteArray>
#include <QDebug>
class InterpreteAsUtf7 {
public:
static QString decodeUtf7(const QByteArray& utf7Data);
private:
static QString processBase64Segment(const QByteArray& base64Buffer, bool& errorFlag);
static QString convertToUtf16LE(const QByteArray& decodedBytes, bool& errorFlag);
};
QString InterpreteAsUtf7::decodeUtf7(const QByteArray& utf7Data) {
QString result;
QByteArray base64Buffer;
bool inBase64 = false;
bool decodingError = false;
for (char c : utf7Data) {
if (c == '+') {
if (inBase64) {
result += "+" + base64Buffer; // Unclosed Base64 section treated as literal
base64Buffer.clear();
}
inBase64 = true;
continue;
}
if (c == '-' && inBase64) {
result += processBase64Segment(base64Buffer, decodingError);
base64Buffer.clear();
inBase64 = false;
continue;
}
if (inBase64) {
base64Buffer.append(c);
} else {
result += QChar(c); // Literal character
}
}
if (inBase64) {
result += "+" + base64Buffer; // Unclosed Base64 treated as literal
}
return result;
}
QString InterpreteAsUtf7::processBase64Segment(const QByteArray& base64Buffer, bool& errorFlag) {
QByteArray decodedBytes = QByteArray::fromBase64(base64Buffer);
if (decodedBytes.isEmpty()) {
errorFlag = true;
qWarning() << "[WARNING] Base64 decoding failed for:" << base64Buffer;
return QString();
}
return convertToUtf16LE(decodedBytes, errorFlag);
}
QString InterpreteAsUtf7::convertToUtf16LE(const QByteArray& decodedBytes, bool& errorFlag) {
if (decodedBytes.size() % 2 != 0) {
errorFlag = true;
qWarning() << "[WARNING] Decoded bytes not aligned for UTF-16:" << decodedBytes;
return QString();
}
QString result;
for (int i = 0; i < decodedBytes.size(); i += 2) {
ushort codeUnit = static_cast<uchar>(decodedBytes[i]) |
(static_cast<uchar>(decodedBytes[i + 1]) << 8);
result.append(QChar(codeUnit));
}
return result;
}
int main() {
QByteArray utf7Data = "Hello, +Z1TA-"; // UTF-7 encoded string for "Hello, 世界"
QString decodedText = InterpreteAsUtf7::decodeUtf7(utf7Data);
qDebug() << "Original UTF-7:" << utf7Data;
qDebug() << "Decoded UTF-7:" << decodedText;
return 0;
}
我发现两个错误,
首先:编码的
世界
应该是ThZ1TA
我就是这样发现的:
echo -n 世界 | iconv -t UTF-16 | tail -c 4 | base64
第二:
convertToUtf16LE
如果翻转字节就可以工作
ushort codeUnit = static_cast<uchar>(decodedBytes[i + 1]) |
(static_cast<uchar>(decodedBytes[i]) << 8);