Encoding.UTF8.GetBytes(Encoding.UTF8.GetString(x))
返回任意字节数组x
的原始字节数组?
在回答另一个问题时提到,但回答者没有解释为什么。
==
来比较序列,这是不起作用的。SequenceEquals()
或仅仅查看它们),它们并不总是相同的。这种情况可能发生在x
是一个无效的 UTF-8 编码字符串时。0xFF
的 1 字节序列不是有效的 UTF-8。那么 Encoding.UTF8.GetString(new byte[] { 0xFF })
返回什么?它是 �,U+FFFD,替换字符。当然,如果你对其调用 Encoding.UTF8.GetBytes()
,它也不会返回 0xFF
。SequenceEqual
扩展方法,非常有用。 - PyreneesJimEncoding
类被设计成能够往返转换数据,但是它们被设计成往返转换的数据是 char
数据,编码为 byte
,而不是相反的方向。这意味着,在所涉及的 Encoding
的能力范围内,每个 char
值都有一个对应的编码值(1个或多个)在 byte
值中,可以完全还原成相同的 char
值。(值得注意的是,并非所有的 Encoding
都能够支持所有可能的 char
值进行此操作 - 例如,Encoding.ASCII
只能支持 [0, 128)
范围内的 char
值。) Encoding
是将 char
数据转换为 byte
数据,然后在另一端再次转换回来的绝佳方式。 (如果您想支持所有可能的字符串,则需要使用基于Unicode的其中一种 Encoding
,例如 Encoding.Unicode
或 Encoding.UTF8
。) byte
开始怎么办?好吧,根据所涉及的编码,您正在使用的 byte
可能实际上不是 Encoding
曾经输出的序列。 您需要将 Encoding.GetBytes
视为编码操作,将 Encoding.GetChars
/ Encoding.GetString
视为解码操作,因此您从任意字节数组开始并尝试解码它们。字符串
,而是图像。因此,如果您拿一串任意的字节,将其解码为JPEG图像的可能性有多大呢?显然,答案非常非常渺茫。更有可能的是,您的字节将沿着解码器中的某个路径走下去,它会说,“哇,我没想到那个字节会出现在那个字节后面”,并且会尽力处理数据,假设它是一个损坏的有效JPEG文件。
当您将任意字节数组转换为字符串时,会发生完全相同的事情。 UTF-8编码有关于如何对128及以上的char
值进行编码的特定规则,其中之一规定,您只会在匹配类似110xxxxx
、1110xxxx
或11110xxx
的模式之后看到与位模式10xxxxxx
匹配的字节,这些模式“介绍”了多字节序列(多个表示单个char
的byte
)。因此,如果您的数据包含与预期的“介绍者”之一不匹配的模式10xxxxxx
的字节,则编码器只能假定数据已被某种方式损坏。它会插入一个字符,表明:“编码数据出现了严重问题。我已尽力。这就是出错的地方。” 设计Unicode的人预见了这种情况,并创建了一个具有这种精确含义的字符:替换字符。
char
字符串中往返传输byte
,并且遇到这种情况,则有问题的byte
的实际值会丢失,而是插入替换字符。当您尝试将string
转换回byte
数组时,它会对替换字符进行编码,而不是原始数据。原始数据会丢失。char
数据转换为byte
数据的方法。如果您想将byte
数据转换为char
数据,则需要针对该特定目的设计的编码。幸运的是,这些编码已经存在。维基百科上有一个相当全面的列表供您选择。 :-)Convert.ToBase64String
和Convert.FromBase64String
公开。字符编码(特别是UTF8)可能对于相同的代码点有不同的形式。
因此,当您转换为字符串并返回时,实际字节可能表示一个不同(规范化)的形式。
另请参见String.Normalize(NormalizationForm.System.Text.NormalizationForm.FormD)
另请参见:
Some Unicode sequences are considered equivalent because they represent the same character. For example, the following are considered equivalent because any of these can be used to represent "ắ":
"\u1EAF" "\u0103\u0301" "\u0061\u0306\u0301"
However, ordinal, that is, binary, comparisons consider these sequences different because they contain different Unicode code values. Before performing ordinal comparisons, applications must normalize these strings to decompose them into their basic components.
该页面附带了一个漂亮的示例,展示了哪些编码始终是规范化的。
var a = new byte[] { 1 };
var b = new byte[] { 1 };
bool res = a == b;
==
比较字节数组吗?那可能只会比较它们的引用,你可能需要循环比较数组中每个元素是否相等。 - Matthew