Encoding.UTF8.GetString和Encoding.UTF8.GetBytes彼此不相反的原因是什么?

时间:2017-07-31 07:53:34

标签: c# .net utf-8

可能我错过了一些东西,但我不明白为什么Encoding.UTF8.GetString和Encoding.UTF8.GetBytes不能互相反转?

在以下示例中,myOriginalBytes和asBytes不相等,即使它们的长度不同。谁能解释我错过了什么?

byte[] myOriginalBytes = GetRandomByteArray();
var asString = Encoding.UTF8.GetString(myOriginalBytes);
var asBytes = Encoding.UTF8.GetBytes(asString);

1 个答案:

答案 0 :(得分:16)

如果你从一个有效的UTF-8字节序列开始,它们是反转的,但如果你只是以一个任意字节序列开始它们就不会。

让我们来看一个具体而简单的例子:单个字节0xff。这不是任何文本的有效UTF-8编码。所以如果你有:

byte[] bytes = { 0xff };
string text = Encoding.UTF8.GetString(bytes);

...你最终将text作为单个字符U+FFFD,“Unicode替换字符”,用于表示解码二进制数据时出错。您最终将使用任何无效序列的替换字符 - 因此,如果以0x80开头,则会获得相同的文本。显然,如果多个二进制输入被解码为相同的文本输出,则它不可能是完全可逆的变换。

如果你有任意二进制数据,你应该使用Encoding从中获取文本 - 你应该使用Convert.ToBase64String或者十六进制。 Encoding用于自然文本的数据。

如果你走向相反的方向,就像这样:

string text = GetRandomText();
byte[] bytes = Encoding.UTF8.GetBytes(text);
string text2 = Encoding.UTF8.GetString(bytes);

...我希望text2等于text,除了您开始使用无效的文本的奇怪情况,例如与“一半”代理对。