【发布时间】:2011-04-12 23:00:39
【问题描述】:
我正在尝试将 Gzip 序列化对象存储到 Active Directory 的“扩展属性”中,更多信息 here。根据oM syntax 的 64,此字段是一个 Unicode 字符串。
将二进制 blob 存储为 Unicode 的最有效方法是什么?一旦我解决了这个问题,剩下的就是小菜一碟了。
【问题讨论】:
标签: c# .net unicode encoding utf-8
我正在尝试将 Gzip 序列化对象存储到 Active Directory 的“扩展属性”中,更多信息 here。根据oM syntax 的 64,此字段是一个 Unicode 字符串。
将二进制 blob 存储为 Unicode 的最有效方法是什么?一旦我解决了这个问题,剩下的就是小菜一碟了。
【问题讨论】:
标签: c# .net unicode encoding utf-8
通常,这是在字节和 Unicode 文本之间进行转换的方式:
// string from bytes
System.Text.Encoding.Unicode.GetString(bytes);
// bytes from string
System.Text.Encoding.Unicode.GetBytes(bytes);
编辑:
但由于并非所有可能的字节序列都是有效的 Unicode 字符串,因此您应该使用一种可以从任意字节序列创建字符串的方法:
// string from bytes
Convert.ToBase64String(byteArray);
// bytes from string
Convert.FromBase64String(base64Encoded);
(感谢指出这一点的 @Timwi!)
【讨论】:
Encoding.Unicode 封装了 UTF-16,并不是所有的字节数组都是有效的 UTF-16。例如,考虑具有奇数字节的数组,或具有单独代理的字节序列。两者都不是有效的 UTF-16,并且会生成一个不会转回原始字节数组的字符串。
System. Text .Encoding 中的编码旨在对 text 进行编码。您应该使用为任意字节数据设计的编码。 Base64 就是一个例子。
Encoding.ASCII.GetString(new byte[] { 63 }),然后运行Encoding.ASCII.GetString(new byte[] { 129 })(提示:两者的答案相同)。您正在查看一个可能代表 Latin-1 (ISO-8859-1) 或 Windows-1252 的文件。然而,即使不是所有 256 个可能的值都有一个有效字符。非 Unicode 编码将几个可能的字节值变成问号。
当然,有很多方法可以可靠地将任意字节数组打包成 Unicode 字符,但没有一种方法非常有效。 非常不幸 ActiveDirectory 会选择对非文本数据使用 Unicode。就像用一个字符串来表示一个 32 位整数,或者像用 Nutella 来写一封情书。
我的建议是“谨慎行事”并使用基于 ASCII 的编码,例如 base64。我推荐这个的原因是因为已经有一个内置的 .NET 实现:
var base64Encoded = Convert.ToBase64String(byteArray);
var original = Convert.FromBase64String(base64Encoded);
理论上,通过使用更多的 Unicode 字符集,您可以提出比这更有效的编码。但是,为了做到这一点可靠,您需要对 Unicode 有相当多的了解。
【讨论】: