我一直在阅读很多资料,但我仍然对如何计算它感到困惑。 我正在做一个练习,问:
以下哪个比特序列(以十六进制数表示)表示有效的UFT-8字符串,如果它们是有效的UTF-8字符串,则比特序列对应的代码数量是多少?
0x30c0 0x303C 0xE0ADAA 0x3AA
答案 0 :(得分: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<'
啊,啊!没有例外。这是正确的UTF-8,对应于2个代码点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(décimal)。那是十六进制......
>>> "{: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'
所以它是:这是与digit 4 in Oriya writing system对应的代码点。
答案 1 :(得分:1)
问题非常糟糕。这些都是数字,而不是字符串。我怀疑这意味着代表字节序列,在这种情况下,他们应该把它写成:
0x30 0xc0
0x30 0x3C
0xE0 0xAD 0xAA
0x03 0xAA
......或类似的东西。
如果这实际上是问题意味着什么(不清楚),那么可以通过琐碎的检查看出哪些是无效的UTF-8:
0xc0
永远不会有效UTF-8。0xaa
,没有多字节序列的有效第一个字节。OR ,您可以尝试让计算机对其进行解码,并且会为无效的计算机提供错误。例如,使用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
>>>