首页 > 解决方案 > 将十六进制转换为十六进制代码点

问题描述

我有一个像这样的十六进制代码:

\xf0\x9f\x94\xb4

我想这样编码:

1F534

如何使用 python 2.7 中的方法对其进行转换?

谢谢

标签: pythonhexencodeutf

解决方案


在这里,您只是在问:如何使用(字节)字符串找到 utf8 中表示的字符的 unicode 代码'\xf0\x9f\x94\xb4'

在 Python3 中,它很简单:

>>> hex(ord(b'\xf0\x9f\x94\xb4'.decode()))
'0x1f534'

在使用 --enable-unicode=ucs4 编译的 Python2 版本中,它或多或少是相同的:

>>> hex(ord('\xf0\x9f\x94\xb4'.decode('utf-8')))
'0x1f534'

但是在您发表评论之后,您就有了一个使用 --enable-unicode=ucs2 编译的 Python 2.7 版本。在这种情况下,Unicode 字符串实际上包含字符串的 UTF16 表示:

>>> print [hex(ord(i)) for i in '\xf0\x9f\x94\xb4'.decode('utf-8')]
['0xd83d', '0xdd34']

无法直接找到 U+1F534 大红圈字符的真正 unicode 代码点。

最后一个选项是手动解码 utf8 序列。您可以在wikipedia上找到 UTF8 编码的描述。以下函数采用 Unicode 字符的 utf-8 表示并返回其代码点:

def from_utf8(bstr):
    b = [ord(i) for i in bstr]
    if b[0] & 0x80 == 0: return b
    if b[0] & 0xe0 == 0xc0:
        return ((b[0] & 0x1F) << 6) | (b[1] & 0x3F)
    if b[0] & 0xf0 == 0xe0:
        return ((b[0] & 0xF) << 12) | ((b[1] & 0x3F) << 6) | (b[2] & 0x3F)
    else:
        return ((b[0] & 7) << 18) | ((b[1] & 0x3F) << 12) | \
               ((b[2] & 0x3F) << 6) | (b[3] & 0x3F)

请注意,这里没有进行任何控制来确保字符串是单个字符的正确 UTF-8 表示形式......但至少它给出了预期的结果:

>>> print hex(from_utf8("\xf0\x9f\x94\xb4"))
0x1f534

推荐阅读