UTF-8和Unicode转换

1. 小小介绍

要说utf-8,就要先大概说一下它的大哥----“unicode"。基本的ASCII定义了128个字符,从0x00-0x7f,即使后面扩展的ASCII也只能表示256个字符,即0x00-0xff。这些字符表示英文是足够了,但是对于其他语言就显得捉襟见肘了,例如咱们的汉字。于是我们就用2个字符来表示汉字了。但后来2个字符也不够了,就慢慢拓展到3个字符。美国也意思到需要一种表示全世界字符的标准,于是,unicode就这么诞生了。

unicode 规定了全球所有字符统一在一个集合,集合里面的元素互不相同。这样就为所有字符定义了一个序列,称之为码点。

unicode虽然规定了码点,但是没有规定编码方式,比如只知道“0”的码点是48(0x30),可以表示为0x00 0x30,也可以表示为0x00 0x00 0x30,只要最后的结果是码点就行。为了将所有字符正确表示,最开始使用4个字符表示unicode。确实可以表示每个字符,但是对于那些单个字符、两个字符表示的码点就太占用空间了。

这时候,变长编码存储的utf-8就出来了。

2. 闪亮登场

utf-8是一种可变长字符编码,使用1~4个字符对unicode字符集中有效码点进行编码。它规定如下:

  • 对于单个字符,高位 bit7:0,兼容ASCII码;
  • 对于多个字符长度n,第一个字节的bit7…bit[8-n]:1, bit[7-n]:0,其余bit进行存储序列的一部分;对于剩下的n-1个字节,bit8-bit7:10,其于bit全部用码点的剩余部分来填充;

关系表如下,x表示码点的某个bit位

码点的位数码点起值码点终值Byte 1Byte 2Byte 3Byte 4Byte 5Byte 6
7U+0000U+007F10xxxxxxx
11U+0080U+07FF2110xxxxx10xxxxxx
16U+0800U+FFFF31110xxxx10xxxxxx10xxxxxx
21U+10000U+1FFFFF411110xxx10xxxxxx10xxxxxx10xxxxxx
26U+200000U+3FFFFFF5111110xx10xxxxxx10xxxxxx10xxxxxx10xxxxxx
31U+4000000U+7FFFFFFF61111110x10xxxxxx10xxxxxx10xxxxxx10xxxxxx

3. 敲个例子

3.1 unicode转换成utf-8

给定一个Unicode码点,可以根据二进制的bit有效位数,快速判断使用utf-8存储的有效bytes,然后套用规则即可。

unicode码点查找

Unicode code pointcharacterUTF-8 (hex.)name
U+0400Ѐd0 80CYRILLIC CAPITAL LETTER IE WITH GRAVE

如上 Ѐ字符的码点是U+0400,使用二进制表示0x400,为 0100 0000 0000,得知有效bit为11,对照上表,utf-8使用2个字符进行表示,因此格式为" 0x110x xxxx 0x10xx xxxx"。从码点的二进制低位开始数数填充。参照上面的颜色 0x1101 0000 0x1000 0000,转换为16进制就是0xd0 0x80

python代码实现:

# unicode_str 可以改为我们实际的字符
unicode_str = "Ѐ"
# .encode 是 Python 中字符串(str)对象的一个方法,用于将字符串转换为字节对象(bytes)
utf8_bytes = unicode_str.encode('utf-8')
print(utf8_bytes)

运行之后,打印如下:

b'\xd0\x80'

3.2 utf-8转unicode

给定utf-8转换成unicode直接按照表格顺序转换就行了,例如给定0xe5 0xb5 0x8c0xe5 0xaf 0xbb两段utf-8编码,我们需要分别先表示出其二进制:

UTF-8二进制
0xe5 0xb5 0x8c1110 0101 1011 0101 1000 1100
0xe5 0xaf 0xbb1110 0101 1010 1111 1011 1011

然后对照上面的表格,去掉每个bytes前面的固定字段后就为:0101 1101 0100 1100 和 0101 1011 1111 1011,转换为16进制就是5d4c和5bfb。

python编码如下:

# 定义一个 UTF-8 编码的字节序列
utf8_bytes = b'\xe5\xb5\x8c\xe5\xaf\xbb'
# 使用 decode 方法将 UTF-8 字节序列转换为 Unicode 字符串
unicode_str = utf8_bytes.decode('utf-8')
print(unicode_str)

for char in unicode_str:
    unicode_code_point_hex = format(ord(char), 'x')
    utf8_encoded_value = char.encode('utf-8')
    print(f"'{char}' 的 utf-8是{utf8_encoded_value}, Unicode 码点是: {ord(char)}")

运行后,输出如下:

嵌寻
'嵌' 的 utf-8b'\xe5\xb5\x8c', Unicode 码点是: 23884
'寻' 的 utf-8b'\xe5\xaf\xbb', Unicode 码点是: 23547

通过以上代码,就可以根据utf-8快速找到其对应的unicode码点值了。

参考: UTF-8编码 - 真正的飞鱼 - 博客园

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

来鸟 鸣间

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值