最近在研究IOS手机备份的数据,里面的微信数据中,每一个微信账号对应一个文件:mmsetting.archive

用来保存此账号的详细信息。

该文件是一个加强版的plist文件(此文件使用的是plist格式,但却包含汉字)

该文件是二进制数据,其中的汉字保存的是Unicode码,并且这个码位是被拆分成2个数字的。例如:

95, 174, 79, 225, 86, 226, 150, 31

对应的是:“微信团队” 四个字

 

转换为字符串: char* s1 = "\u5fae\u4fe1\u56e2\u961f";   //很简单吧

(95, 174 对应于“微” 字 ,它们的十六进制分别是:0x5f  , 0xae   .以此类推)

但是,我们从文件中获取的汉字很多,并且是不确定的。所以,代码里应该是这样的:

CString s1;
s1.Format(L"\\u%x%x\\u%x%x\\u%x%x\\u%x%x", 95, 174, 79, 225, 86, 226, 150, 31);

这样得到的是字符串:\u5fae\u4fe1\u56e2\u961f   ,而不是汉字,明显是错误的。(使用std::wstring 也一样)

 

正确的方法应该是:直接把Unicode码 添加进wstring对象

    std::wstring str;
    int c;
    c = 95 * 16 * 16 + 174; //得到unicode码对应的整型
    str.push_back(c);   //这个函数只能添加单个字符,而在宽字节环境下,每个字符的unicode码是唯一的

    c = 79 * 16 * 16 + 225;
    str.push_back(c);

    c = 86 * 16 * 16 + 226;
    str.push_back(c);

    c = 150 * 16 * 16 + 31;
    str.push_back(c);    

 

通用函数如下:

static wstring unicode2string(const vector<unsigned char>& charBytes)
{
    std::wstring str;
    int code = 0;
    unsigned char c1, c2;
    auto it = charBytes.begin();
    while ( it != charBytes.end())
    {
        c1 = *it;
        if (++it != charBytes.end())
        {
            c2 = *it;
            code = c1 * 16 * 16 + c2;
            str.push_back(code);

            ++it;
        }
    }

    return str;
}

 不能使用std::string

 

posted on 2018-03-14 18:29  Love流浪的猪  阅读(4285)  评论(0编辑  收藏  举报