Dot-Net

是否有將二進制數據打包成 UTF-16 字元串的標準技術?

  • February 16, 2017

(在 .NET 中)我將任意二進制數據儲存在一個字節中$$ $$(例如圖像)。現在,我需要將該數據儲存在一個字元串中(遺留 API 的“註釋”欄位)。是否有將這種二進制數據打包字元串的標準技術?通過“打包”,我的意思是對於任何相當大的隨機數據集,bytes.Length/2與**packed.Length 大致相同;因為兩個字節或多或少是一個字元。

兩個“明顯”的答案不符合所有標準:

string base64 = System.Convert.ToBase64String(bytes)

沒有非常有效地使用字元串,因為它只使用大約 60,000 個可用字元中的 64 個字元(我的儲存是System.String)。一起去

string utf16 = System.Text.Encoding.Unicode.GetString(bytes)

更好地利用了string,但它不適用於包含無效 Unicode 字元的數據(比如不匹配的代理對)。 這篇 MSDN 文章展示了這種精確(差)的技術。

讓我們看一個簡單的例子:

byte[] bytes = new byte[] { 0x41, 0x00, 0x31, 0x00};
string utf16 = System.Text.Encoding.Unicode.GetString(bytes);
byte[] utf16_bytes = System.Text.Encoding.Unicode.GetBytes(utf16);

在這種情況下bytesutf16_bytes是相同的,因為原始字節是 UTF-16 字元串。使用 base64 編碼執行相同的過程會得到 16 個成員的base64_bytes數組。

現在,使用無效的 UTF-16 數據重複該過程:

byte[] bytes = new byte[] { 0x41, 0x00, 0x00, 0xD8};

您會發現utf16_bytes與原始數據不匹配。

我編寫了在無效 Unicode 字元之前使用 U+FFFD 作為轉義的程式碼;它有效,但我想知道是否有比我自己製作的更標準的技術。更不用說,我不喜歡將DecoderFallbackException**作為檢測無效字元的方式。

我想您可以將其稱為“基本 BMP”或“基本 UTF-16”編碼(使用 Unicode 基本多語言平面中的所有字元)。是的,理想情況下我會遵循肖恩斯蒂爾的建議並傳遞字節$$ $$.


我將接受 Peter Housel 的建議作為“正確”答案,因為他是唯一一個接近建議“標準技術”的人。


編輯base16k 看起來更好。Jim Beveridge 有一個實現

閱讀您的問題後,我偶然發現了Base16k 。嚴格來說不是一個標準,但它似乎執行良好並且很容易在 C# 中實現。

我可以建議你使用base64 嗎?它可能不是最有效的儲存方式,但它確實有它的好處:

  1. 您對程式碼的擔憂已經結束。
  2. 如果有的話,您與其他播放器的兼容性問題最少。
  3. 如果在轉換、導出、導入、備份、恢復等過程中將編碼字元串視為 ASCII,您也不會有任何問題。
  4. 如果您曾經摔死或最終在公共汽車下或其他東西下,任何接觸到評論欄位的程序員都會立即知道它是base64,而不是假設它都是加密的或其他東西。

引用自:https://stackoverflow.com/questions/646974