-1

我一直在阅读很多资料,但我仍然对如何计算它感到困惑。我正在做一个练习,询问:

以下哪个位序列(以十六进制数字表示)代表有效的 UFT-8 字符串,如果它们是有效的 UTF-8 字符串,那么位序列对应多少个代码?

0x30c0
0x303C
0xE0ADAA
0x3AA
4

2 回答 2

2

第一个定义:UTF-8将 Unicode 代码点编码为 1 到 6 个字节的序列。

0x30C0 使用十六进制表示 2 个字节。假设字节序列中首先出现的高位字节,这相当于 0x30 后跟 0xC0。你可以用 Python 3 来写:

>>> seq = b"\x30\xC0"
>>> seq
b'0\xc0'

假设这可能是一个 UTF-8 编码的字节流,我们可以尝试以下decode方法:

>>> seq.decode("UTF-8")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc0 in position 1: invalid start byte

???不工作。该序列不是正确的 UTF-8。


让我们对下一个序列做同样的事情:

>>> seq = b"\x30\x3C"
>>> seq.decode("UTF-8")
'0<'

啊啊!没有例外。这是对应于 2 个代码点的字符串的正确 UTF-8 0<


第三个很有趣:

>>> seq = b"\xE0\xAD\xAA"
>>> seq.decode("UTF-8")
'୪'
>>> len(seq.decode("UTF-8"))
1

这 3 个字节仅用于编码一个代码点。但这是哪个字符……嗯……“代码点”?Python 具有以下ord功能:

>>> ord(seq.decode("UTF-8"))
2922

代码点 2922(十进制)。那是十六进制...

>>> "{:04X}".format( ord(seq.decode("UTF-8")) )
'0B6A'

所以字节序列0xE0 0xAD 0xAA编码为 UTF-8 的 unicode 代码点U+0B6A。但那是哪个角色?Python 嵌入了一个模块来查询 Unicode 数据库:

>>> import unicodedata
>>> unicodedata.name( seq.decode("UTF-8") )
'ORIYA DIGIT FOUR'

就是这样:这是奥里亚语书写系统中数字 4对应的代码点。

于 2013-06-25T17:54:12.547 回答
1

这个问题提出的非常糟糕。这些都是数字,而不是字符串。我怀疑这意味着表示字节序列,在这种情况下,他们应该将其写为:

0x30 0xc0
0x30 0x3C
0xE0 0xAD 0xAA
0x03 0xAA

...或类似的东西。

如果这实际上是问题的意思(不清楚),那么可以通过简单的检查来看出哪些是无效的 UTF-8:

  • 第一个无效。该字节0xc0永远不是有效的 UTF-8。
  • 第二个仅包含 ASCII,因此根据定义它也是有效的 UTF-8。
  • 第三个乍一看是正确的格式(第一个字节大于 0xc1,第二个和第三个在 0x80 和 0xbf 之间)。你可以按照UTF-8的定义,用纸笔解码,看看是否有效。
  • 第四个无效:它有一个连续字节0xaa,但没有有效的多字节序列的第一个字节。

或者,你可以试着让计算机解码它们,它会给你一个错误的错误。例如,使用 Python 版本 3,

>>> bytes([0x30,0xc0]).decode('utf-8')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc0 in position 1: invalid start byte
>>> bytes([0x30,0x3c]).decode('utf-8')
'0<'
>>> bytes([0xe0,0xad,0xaa]).decode('utf-8')
'୪'
>>> bytes([0x03,0xaa]).decode('utf-8')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xaa in position 1: invalid start byte
>>> 
于 2013-06-25T17:55:20.517 回答