(在 .NET 中)我将任意二进制数据存储在byte[](例如图像)中。现在,我需要将该数据存储在一个字符串中(遗留 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);
在这种情况下bytes和utf16_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 基本多语言平面中的所有字符)。是的,理想情况下,我会遵循Shawn Steele 的建议并传递byte[]。
我将接受 Peter Housel 的建议作为“正确”答案,因为他是唯一一个接近建议“标准技术”的人。