将QString转换为非ascii字符的utf16十六进制表示

时间:2016-08-08 13:59:01

标签: string qt unicode hex ascii

我要将QString转换为十六进制表示,一切正常,直到我放了一些特殊字符,如'€':

QString l_str = "How are you";
qDebug() << "hex:     " << l_str.toUtf8().toHex();
qDebug() << "readable:" << l_str.toUtf8();

打印出来:

  

hex:&#34; 486f772061726520796f753f&#34;

     

可读:&#34;你好吗?&#34;

因此很容易将十六进制值转换回ascii,只是两个值(48 = H等)ascii char的十六进制表示,它足以迭代并转换每两个字符。

如果我设置l_str =&#34;你好吗?&#34;,并且utf8中的十六进制符号是&#34; e282ac&#34;这是6个值,结果如下:

  

hex:&#34; 48 e282ac 77206172e282ac20796f753f&#34;

但是如何将其恢复为可读字符串?

如果转换产生utf16字符串会更好:

  

hex:&#34; 0048006F20AC00200061007220AC00200079006F0075003F&#34;

考虑一下&#34;何你是&#34; string是在运行时创建的(所以没有QStringLiteral可用),我不能使用 auto 关键字。

2 个答案:

答案 0 :(得分:2)

您可以将字符串转换为utf8 / 16,然后将保存该字符串的缓冲区转换为十六进制表示形式。可以按相反的顺序执行这些步骤,从十六进制到utf8 / 16到字符串。

toUtf16Hex函数预先设置一个字节顺序标记,以便小端和大端主机都可以正确解码Utf16表示。

// https://github.com/KubaO/stackoverflown/tree/master/questions/str-to-utf-38831190
#include <QtCore>

QByteArray toUtf8Hex(const QString & str) {
   return str.toUtf8().toHex();
}
QString fromUtf8Hex(const QByteArray & hex) {
   return QString::fromUtf8(QByteArray::fromHex(hex));
}

QByteArray toUtf16Hex(QString str) {
   str.prepend(QChar::ByteOrderMark);
   // It is OK to use `fromRawData` since toHex copies it.
   return QByteArray::fromRawData(
            reinterpret_cast<const char*>(str.constData()), (str.size()+1)*2).toHex();
}
QString fromUtf16Hex(const QByteArray & hex) {
   const QByteArray utf16 = QByteArray::fromHex(hex);
   return QString::fromUtf16(reinterpret_cast<const quint16*>(utf16.data()));
}

int main() {
   const QString str = QStringLiteral("H€w ar€ you?");

   // To Utf8 and back
   const QByteArray hex8 = toUtf8Hex(str);
   Q_ASSERT(fromUtf8Hex(hex8) == str);

   // To Utf16 and back
   const QByteArray hex16 = toUtf16Hex(str);
   Q_ASSERT(fromUtf16Hex(hex16) == str);
}

答案 1 :(得分:0)

我找到了一个黑客但有效的解决方案:

QString l_str = "Ho€ Ar€ you?";
qDebug() << "hex:     " << l_str.toUtf8().toHex();
qDebug() << "readable:" << l_str.toUtf8();

QTextCodec* l_codec = QTextCodec::codecForName("UTF-16");

QByteArray l_string = l_codec->fromUnicode(l_str).toHex();
qDebug() << "utf16 encoded: " << l_string;

QByteArray l_reversed;

for(int i=0; i < l_string.length(); i=i+4)
{
    QString l_hex_chars_1 = l_string.mid(i, 2);
    QString l_hex_chars_2 = l_string.mid(i+2, 2);
    l_reversed.append(l_hex_chars_2);
    l_reversed.append(l_hex_chars_1);
}

QByteArray l_bom("feff");
if(l_reversed.startsWith(l_bom))
{
    l_reversed.remove(0, l_bom.length());
}

QString l_res;

for(int i=0; i < l_reversed.length(); i=i+4)
{
    QString l_hex_chars_1 = l_reversed.mid(i, 2);
    QString l_hex_chars_2 = l_reversed.mid(i+2, 2);

    int l_val = l_hex_chars_1.toInt(0,16)*256+l_hex_chars_2.toInt(0,16);
    QChar l_char(l_val);
    l_res.append(l_char);
}
qDebug() << "back to string: " << l_res;

打印出来:

  

hex:&#34; 48e282ac77206172e282ac20796f753f&#34;

     

可读:&#34;你好吗?&#34;

     

utf16编码:&#34; fffe4800ac207700200061007200ac20200079006f0075003f00&#34;

     

字节反转:&#34; 004820ac007700200061007220ac00200079006f0075003f&#34;

     

回到字符串:&#34;你好吗?&#34;