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