【问题标题】:Why can't I decode any byte using utf-8?为什么我不能使用 utf-8 解码任何字节?
【发布时间】:2022-01-11 12:51:25
【问题描述】:

不是编码专家,正在努力学习。

我有一个拉丁编码的文件,当我尝试使用“utf-8”读取和解码时,我收到以下错误:

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xa0 in position 0: invalid start byte

为什么 utf-8(每个字符使用 1-4 个字节)不能解码 latin1(每个字符 1 个字节)。

latin1 是 utf-8 的子集吗?我对此很迷茫,所以任何事情都有帮助。

【问题讨论】:

  • UTF-8 具有某些 规则,任何字节序列都需要遵循这些规则才能成为有效的 UTF-8。独立的A0 已经违反了这些规则。见What Every Programmer Absolutely, Positively Needs To Know About Encodings And Character Sets To Work With Text
  • Unicode 是 ISO-8859 字符集的超集,但 UTF-8 是所有 Unicode 的多字节编码,而 ISO-8859 是单字节编码只是 Unicode 的前 256 个代码点。因此,UTF-8 需要两个字节来编码该范围内的非 ASCII 字符。
  • 也就是说,latin1 不是 utf-8 的子集,但它编码的 characters 集合是 Unicode 的子集。字符集与其字节编码之间的区别是单字节编码方案容易模糊的。
  • 感谢您的所有回答!将它们作为回复提交,以便我可以将它们视为有效?
  • 注意:“utf-8”是原始字节的格式,不是目的地。 Python 在内部使用“增强的 Unicode 字符集”(将其视为黑盒,真正的编码是“可变的”,但除非您正在为 Python 做 C 模块,否则您不应该关心它)。

标签: python encoding


【解决方案1】:

有两个不同的概念被混淆了。

字符集是字符的顺序,编号从 0 到 ...

编码是一种将字符集中的数字表示为字节序列的方式。


对于最多包含 256 个字符的字符集,可以进行简单的单字节编码。

对于较大的字符集,需要多字节编码。它们可以分为两种类型:固定大小,其中每个字符使用相同的字节数,可变大小,其中不同的字节数用于表示不同的字符。

固定大小编码的示例都是单字节编码和 UTF-32。

可变大小编码的示例是 UTF-8 和各种 UTF-16 编码。


Latin-1 既是一个字符集(包含 ASCII 字符及其用于编写西欧语言的附加字符),又是其对应的单字节编码(有 256 个字符)

Unicode 是一个字符集,包含(或旨在包含)用于编写所有已知语言的所有字符。毫不奇怪,它比 256 个字符大得多。

UTF-8 只是 Unicode 的一种多字节编码,也是一种可变大小的编码。每个 UTF-8 序列的第一个字节告诉您附加个字节如何跟随它来编码单个 Unicode 代码点。

Unicode 和 Latin-1(字符集)的前 256 个代码点重合。也就是说,Latin-1 是 Unicode 的一个子集。

UTF-8 和 Latin-1 的前 128 个序列重合。之后,他们分道扬镳。在 UTF-8 中,代码点 128 到 255 需要两个字节。第一个字节的格式为 110xxxxxx,第二个字节的格式为 10xxxxxx。这 11 个 x 位可用于编码 Unicode 的其余 Latin-1 子集(加上额外的块)。

字节 0xa0 不是有效的 UTF-8,因为它的二进制扩展为 10100000。多字节 UTF-8 序列的第一个字节总是以至少 两个 1 开头(直观地说, number of 1s 表示序列中的字节数)。

【讨论】:

    猜你喜欢
    • 2018-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-16
    • 1970-01-01
    • 1970-01-01
    • 2018-04-22
    • 1970-01-01
    相关资源
    最近更新 更多