最近在研究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