我们在python字符编码的时候,通常可以看到这样的输出:

>>> '好'.encode()
b'\xe5\xa5\xbd'

 这里的3个十六进制数值是怎么来的,这里做一个解析。“好”字的Unicode编码号是

>>> ord('好')
22909

uft-8编码的规则是

0-127的用一个字节表示,首位为0

128-2047的用2个字节表示,第一个字节首位是110,第二个字节首位是10

2048-65535的用3个字节表示,第一个字节首位是1110,第二个,第三个字节首位都是10

65536及以上的用4个字节表示,第一个字节首位是11110,第二个,第三个,第四个字节首位都是10

22909处于2048到65535之间,所以这个编码的结果是3个字节,

我们将其转换为二进制然后填满这几个字节余下的位就可以了,下面通过笔算来实现这个过程。展示:

python uf8 python uf8编码_十六进制

 

f'{n:0>16b}'这样的代码,以此为例解释,三个字节的字符,由于固定的首位分别是1110,10和10,三个字节总共24位,因此需要填充的字节数量长度是24-4-2-2=16,在转换这个Unicode编码为二进制的时候就把不足16位的前面全部充满0做填充,以便于后面的切割操作。

def GetHex(s: str):
    if s.__len__() != 1:
        return False
    n = ord(s)                              # 得到字符的unicode号
    if n in range(128):                     # Unicode号在0-127之间的
        # 结果是ASCII,只有一位
        return hex(n)
    elif n in range(128, 2049):             # Unicode号在128-2049之间的字符
        # 由2个字节组成,开头分别是110和10
        bn = f'{n:0>11b}'                   # 需要填充的二进制长度为11位
        b1 = f'110{bn[:-6]}'                # 取倒数第6位之前的拼接第一个字节二进制
        b2 = f'10{bn[-6:]}'                 # 取倒数第6位以后的拼接第二个字节二进制
        return f'{hex(int(b1,2))} {hex(int(b2,2))}'
    elif  n in range(2048, 65536):          # Unicode号介于2048到65536的
        # 由3个字节组成,开头分别是1110,10,10
        bn = f'{n:0>16b}'                   # 需要填充的二进制长度为16位
        b1 = f'1110{bn[:-12]}'              # 取倒数12位之前的拼接最右边的二进制
        b2 = f'10{bn[-12:-6]}'              # 取倒数12到倒数第6位之间的拼接中间二进制
        b3 = f'10{bn[-6:]}'                 # 取倒数6位拼接最左边的二进制
        return f'{hex(int(b1,2))} {hex(int(b2,2))} {hex(int(b3,2))}'
    elif n > 65535:                         # Unicode号大于65535的
        # 由4个字节组成,开头分别是11110,10,10,10
        bn = f'{n:0>21b}'                   # 需要填充的二进制长度为21位
        b1 = f'11110{bn[:-18]}'             # 取倒数18位之前的拼接第一个字节二进制
        b2 = f'10{bn[-18:-12]}'             # 取倒数第18位到倒数第12位之间的拼接第二个字节二进制
        b3 = f'10{bn[-12:-6]}'              # 取倒数第12位到倒数第6位之间的拼接第三个字节二进制
        b4 = f'10{bn[-6:]}'                 # 取倒数第6位以后的拼接第四个字节二进制
        return f'{hex(int(b1,2))} {hex(int(b2,2))} {hex(int(b3,2))} {hex(int(b4,2))}'