我问了谷歌上面的问题,并被发送到Difference between UTF-8 and UTF-16?,不幸的是,它没有回答这个问题。
根据我的理解,UTF-8应该是UTF-16的一个子集,意思是:如果我的代码使用UTF-16,并且我提交了一个UTF-8编码的字符串,那么一切都应该是正常的。另一种方式(期望UTF-8和获得UTF-16)可能会导致问题。
对吗?
编辑:澄清为什么链接的SO问题没有回答我的问题:我的问题是在尝试使用WebClient.DownloadString处理JSON字符串时出现的,因为WebClient使用了错误的编码。我从请求中收到的JSON被编码为UTF-8,我面临的问题是:如果我设置了webClient.Encoding = New System.Text.UnicodeEncoding (也称为UTF-16),我是出于安全考虑,也就是能够处理UTF-8和UTF-16请求结果,还是应该使用webClient.Encoding = New System.Text.UTF8Encoding
发布于 2015-09-10 19:27:58
现在还不清楚你所说的“兼容”是什么意思,所以让我们先来了解一些基础知识。
Unicode是基本概念,如果实现得当,UTF-16和UTF-8是两种不同的Unicode编码方式。它们显然是不同的--否则,为什么会有两个不同的概念呢?
Unicode本身并不指定序列化格式。UTF-8和UTF-16是两种可选的序列化格式。
它们是“兼容”的,因为它们可以表示相同的Unicode代码点,但“不兼容”,因为表示完全不同。
与UTF-16相比,UTF-16还有两个额外的特性。实际上有两种不同的编码,UTF-16LE和UTF-16BE。这些字符顺序不同。(UTF-8是字节编码,因此没有字节顺序。)传统UTF-16过去被限制为65,536个可能的字符,少于当前包含的Unicode。这是通过代理来处理的,但是非常旧的和/或损坏的UTF-16实现(正确地标识为UCS-2,而不是“真正的”UTF-16)不支持它们。
为了更具体一点,让我们比较四个不同的代码点。我们选择U+0041、U+00E5、U+201C和U+1F4A9,因为它们很好地说明了不同之处。
U+0041是一个7位字符,因此UTF8只用一个字节来表示它。U+00E5是一个8位字符,因此需要对其进行编码。U+1F4A9位于基本多语言平面之外,因此UTF16用一个代理序列来表示它。最后,U+201C不是上面的任何一种。
以下是以UTF-8、UTF-16LE和UTF-16BE表示的候选字符。
Character | UTF-8 | UTF-16LE | UTF-16BE |
----------+---------------------+---------------------+---------------------+
U+0041 | 0x41 | 0x41 0x00 | 0x00 0x41 |
U+00E5 | 0xC3 0xA5 | 0xE5 0x00 | 0x00 0xE5 |
U+201C | 0xE2 0x80 0x9C | 0x1C 0x20 | 0x20 0x1C |
U+1F4A9 | 0xF0 0x9F 0x92 0xA9 | 0x3D 0xD8 0xA9 0xDC | 0xD8 0x3D 0xDC 0xA9 |举一个明显的例子,如果解释为UTF-16,U+00E5的UTF-8编码将表示完全不同的字符(在UTF-16LE中为U+A5C3,在UTF-16BE中为U+C3A5)。相反,许多UTF-16码根本不是有效的UTF-8序列。所以从这个意义上说,UTF-8和UTF-16是完全不兼容的。
这些是字节值;在ASCII码中,0x00是NUL字符(有时表示为^@),0x41是大写A,0xE5是未定义的;例如,在拉丁文中-1 in表示字符§(在Unicode中也方便地表示为U+00E5 ),但在KOI8-R中它是西里尔字符Е(U+0415),etc.
在现代编程语言中,您的代码应该简单地使用Unicode,并让该语言以适合您的平台和库的方式处理编码的细节。在有些离题的注释中,请参见http://utf8everywhere.org/
https://stackoverflow.com/questions/32499846
复制相似问题