2015-04-30 72 views
-1

我有一個隨機緩衝區。 我需要將它編碼爲unicode字符串(utf16 LE,由windows wide-char規範使用),因此它可以用作PWSTR。例如,當調用StringCchPrintfW時作爲unicode字符串有效地表示一個緩衝區

一個可能的解決方案可以是使用base64。但爲了使它成爲一個Unicode字符串,我將不得不在每個字符後添加一個零字節,這在空間上效率很低。

如果我只打印緩衝區,它可能包含會終止字符串的'\ 0',或者會影響格式化的'%'(也許它可能會被轉義),或者會阻止其他的Unicode字符它被用於格式化。

生成要打印的字符串並在最後解析的代碼將用C#編寫,但緩衝區將在Windows C++中用於格式化並寫入文件。

+0

你有*什麼*的緩衝區?人物?在什麼編碼?爲什麼在使用base64的時候,你有本地函數[將窄多字節字符緩衝區轉換爲寬字符字符緩衝區](https://msdn.microsoft.com/en-us/library/dd319072.aspx)(使用UTF- 16)?另見例如[此頁面全是轉換示例](https://msdn.microsoft.com/en-us/library/ms235631.aspx)。 –

+0

a)那麼你的意思是如何將任意二進制數據表示爲字符串? b)你不是指Unicode,而是UFT16。 c)是的,它對於base64來說是空間低效的,並且有更好的東西(UTF8),但是WIndows需要UTF16。 d)如果編碼正確,\ 0不應該成爲問題。明確地在某處保存長度。 – deviantfan

+0

或者轉換爲任何格式並使用您選擇的壓縮算法將其壓縮存儲。 –

回答

2

這裏有兩種方法我能想到的:

  • 最簡單的一個:通過總結爲0x8000到它的價值轉換每個字節的UTF-16 wchar_t的(即你追加一個0x80的字節)。效率只有50%,但至少可以省掉base64轉換,這會將效率降低到37.5%。

  • 高效但複雜的一種:以15位塊讀取數據(如果總位數不是15的倍數,則在末尾填充空位)。通過將0x4000添加到其值,將每個塊轉換爲UTF-16字符。然後添加值爲0xC000 + n的最終wchar_t,其中n(0 < = n < = 14)是最終塊中填充位的數量。作爲交換一個更復雜的算法,你會得到非常好的效率:93.75%。

兩者的方法的避免在UTF-16格式字符串使用二進制數據的所有的危險:沒有空字節,沒有「%」的字符,沒有代理對,僅可打印字符(其中大部分是中國表意文字)。

+0

謝謝!我不會理解第二種方法。你建議使用哪些字符? 0x4000-0xffff?我認爲其中有些不是'安全的'(如0xFFFF = WEOF)。無論如何,這聽起來像是一個非常好的方向。你能否解釋一下你如何選擇哪些字符是「安全」使用的,哪些字符不是? – user972014

+0

順便說一句,爲什麼避免代理對? – user972014

+1

用我的第二種方法,字符範圍是0x4000 - 0xBFFF(加上0xC000 - 0xC00D爲最後的wchar)。因此避免任何危險區域。避免使用代理,因爲它們只會增加1-2%的效率,但是通過犧牲wchar獨立性(因爲每個高代理必須跟隨一個較低的代理),會爲編碼算法增加更多的限制。 –

相關問題