(在.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)
更好地利用字符串,但它不适用于包含无效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与原始数据不匹配.
我编写的代码使用U + FFFD作为无效Unicode字符之前的转义; 它有效,但我想知道是否有一种比我自己制作的更标准的技术.更何况,我不喜欢抓荷兰国际集团的DecoderFallbackException作为检测无效字符的方式.
我想你可以称之为"基本BMP"或"基本UTF-16"编码(使用Unicode基本多语言平面中的所有字符).是的,理想情况下我会遵循Shawn Steele的建议并传递byte [].
我将把Peter Housel的建议作为"正确"的答案,因为他是唯一接近建议"标准技术"的人.
编辑base16k 看起来更好.Jim Beveridge有一个实现.
我建议你不要使用的base64?它可能不是以存储方式进行存储的最有效方式,但它确实有其好处:
您对代码的担忧已经结束.
如果有的话,你与其他玩家的兼容性问题最少.
如果编码的字符串在转换,导出,导入,备份,还原等过程中被视为ASCII,那么您也不会遇到任何问题.
如果你曾经在公共汽车或其他什么地方摔倒或结束,那么任何掌握评论字段的程序员都会立即知道它是base64并且不会认为它是全部加密的.
读完你的问题后,我偶然发现了Base16k.它不是严格的标准,但它似乎运行良好,并且很容易在C#中实现.