详解 ASCII、Unicode、UTF-32 及 UTF-8

4 篇文章 1 订阅

目录

一、ASCII 字符集和编码

二、Unicode 字符集

2.1 - UTF-32 编码

2.2 - UTF-8 编码

2.3 - Python 字符串的 encode 和 decode 方法



一、ASCII 字符集和编码

计算机只能存储二进制数字 0 和 1,因此无论是文本中的数字、字母、汉字以及 emoji 都需要以某种方式转换成二进制数字进行存储,需要的时候再读出来。

1963 年,ANSI 推出了 ASCII 作为计算机及其他设备的文本字符编码标准。ASCII 支持的字符包含 0 ~ 9 的阿拉伯数字、大小写英文字母、常用的英文符号(!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~)以及控制字符(负责对应换行、回车等特殊的控制功能),每个字符都有一个对应的数字,叫作码点,ASCII 的码点为 0 ~ 127 之间的数字,标准所支持的所有字符以及对应码点的集合叫作字符集

  1. ANSI 的全称是 American National Standards Institute,即美国国家标准学会。

  2. ASCII 的全称是 American Standard Code for Information Interchange,即美国信息交换标准代码。

  3. ASCII 字符集(一共包含 128 个字符):

计算机可以存储 ASCII 码点的二进制,但由于最大的码点是 127,即二进制的长度小于或等于 7,并且计算机一般以 8 比特,即 1 字节,为基本单位读写,所以为了凑整,这些二进制被存储时,会在开头留 0,用固定的 8 比特长度来存储每个字符。

字符码点二进制码点存储在计算机的内容
NUL0000000000
SOH1100000001
... ...... ...... ...... ...
04811000000110000
14911000100110000
... ...... ...... ...... ...
A65100000101000001
B66100001001000010
... ...... ...... ...... ...
~126111111001111110
DEL127111111101111110

这种从字符到计算机能够存储的内容之间的映射叫作编码


二、Unicode 字符集

ASCII 编码一共就适用于 128 个字符,其他语言的字符不够用,于是不同国家和地区开始制定自己的编码标准,比如大陆有国家总局制定的于 1981 年开始实施的 GB2312,港澳台有在 1984 年开始流行的大五码 Big5,后来还有对 GB2312 进行扩展的 GBK,收录了简繁体汉字、日文、韩文等。但是当标准不统一时,乱码问题也随之产生,因为计算机内存里的同一个数字在不同字符集中代表的可能是完全不同的字符

因此大家亟需一种更通用的字符编码,支持不同语言的文字,1991 年 Unicode(统一码、万国码、单一码)字符集发布,目标在于让世界上每个人都能在电脑上阅读自己的文字。随着版本的迭代,Unicode 囊括的字符越来越多,包括汉字、平片假名、藏文、阿拉伯文,甚至古象形文字,2010 年,emoji 也被纳入 Unicode,如今 Unicode 已经包含了超过十四万个字符。Unicode 的每个字符也有对应码点,许多语言都有可以用于查询 Unicode 字符码点的内置函数,例如在 Python 中,可以使用内置函数 ord 获取字符对应的码点(还可以使用内置函数 chr 根据码点获取对应的字符)。

print(ord('A'))  # 65
print(ord('你'))  # 20320

print(chr(65))  # A
print(chr(20320))  # 你

2.1 - UTF-32 编码

注意:字符集只是字符以及字符对应码点的集合,不代表字符一定以对应码点被存储在计算机中,字符编码才是真正定义了字符到计算机存储内容的映射

那么最简单的编码规则自然就是把字符对应的码点直接以二进制存储在计算机中,UTF-32(32-bit Unicode Transformation Format) 编码就是针对 Unicode 这样做的,上面所说的 ASCII 编码也是针对 ASCII 字符集这样做的。

UTF-32 让每个字符都以 32 比特,即 4 字节的长度来存储,位数不够就在前面补 0,32 比特足够表示 Unicode 中的所有字符,固定长度也能帮助计算机明确每个字符的截断范围,但造成的问题是:ASCII 编码中的每个英文字母只要 1 字节,GBK 中的一个汉字只要 2 字节,而在 UTF-32 中则都需要 4 字节。

2.2 - UTF-8 编码

为了改善空间效率,UTF-8(8-bit Unicode Transformation Format)在 1992 年诞生,UTF-8 是针对 Unicode 的可变长度编码,不同于编码后长度固定为 32 比特的 UTF-32,UTF-8 针对不同字符,编码后的长度可以是 32 比特、24 比特、16 比特、8 比特

具体规则是

  1. 码点在 0 ~ 127 范围内的字符直接映射为 1 字节长度的二进制数。

  2. 码点在 128 ~ 2047 范围内的字符映射为 2 字节长度的二进制数。

    UTF-8 为了让计算机知道各个字符之间到底在哪里分割,就让 2 字节编码的第一个字节由 110 开头,第二个字节由 10 开头,Unicode 的二进制码点会被分割成两个部分,填入 UTF-8 编码的数字里

  3. 码点在 2048 ~ 65535 范围内的字符映射为 3 字节长度的二进制数。

    第一个字节由 1110 开头,后面两个字节都由 10 开头,Unicode 的二进制码点会被分割成三个部分,填入 UTF-8 编码的数字中

  4. 码点在 65536 ~ 1114111 范围的字符映射为 4 字节长度的二进制数。

    第一个字节由 11110 开头,后面三个字节都由 10 开头,Unicode 的二进制码点会被分割成四个部分,填入 UTF-8 编码的数字中

码点范围(十进制)二进制码点存储在计算机的内容
0 ~ 1270zzzzzzz0zzzzzzz
128 ~ 204700000yyy yyzzzzzz110yyyyy 10zzzzzz
2048 ~ 65535xxxxyyyy yyzzzzzz1110xxxx 10yyyyyy 10zzzzzz
65536 ~ 1114111000wwwxx xxxxyyyy yyzzzzzz11110www 10xxxxxx 10yyyyyy 10zzzzzz

此处 w、x、y、z 占位符均表示 0 或 1

UTF-8 的优点

  1. 兼容 ASCII。

  2. 节约空间,UTF-8 让 Unicode 中码点小的字符也相应拥有更短的长度,并且通过前缀信息,也能让计算机辨别各字符在内存中的总长度,解决分割不明的问题。

2.3 - Python 字符串的 encode 和 decode 方法

使用 encode 方法可以将字符串以指定的编码规则转换成对应的编码(注意:不是码点);使用 decode 方法可以将编码按照指定的编码规则解码成字符串

# 字符:你
# 码点范围:20320(2048 ~ 65535)
# 二进制码点:01001111 01100000
# 存储在计算机中的内容:11100100 10111101 10100000
# 验证:
print('你'.encode('utf-8'))  # b'\xe4\xbd\xa0' --> 0xe4bda0
print(bin(0xe4bda0))  # 0b11100100 10111101 10100000
print(b'\xe4\xbd\xa0'.decode('utf-8'))  # 你
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,让我来解答你的问题。 首先,我们需要了解一些基本概念: GBK 是一种针对汉字的编码方式,它能够表示所有的中文字符。而 UTF-8 是一种可变长度的编码方式,能够表示世界上所有的字符。 当我们在使用 GBK 编码的网页中嵌入了 UTF-8 编码的内容时,就会出现乱码的情况。同样,当我们在使用 UTF-8 编码的网页中嵌入了 GBK 编码的内容时,也会出现乱码的情况。 为了解决这个问题,我们需要进行编码的转换。具体的步骤如下: 1. 将 GBK 编码的内容转换成 UTF-8 编码的内容: 可以通过以下的方式来实现: ```python import codecs # 打开 GBK 编码的文件 with codecs.open('gbk.txt', 'r', 'gbk') as f: gbk_content = f.read() # 将 GBK 编码的内容转换成 UTF-8 编码的内容 utf8_content = gbk_content.encode('utf-8') # 将 UTF-8 编码的内容写入文件 with codecs.open('utf8.txt', 'w', 'utf-8') as f: f.write(utf8_content.decode('utf-8')) ``` 2. 将 UTF-8 编码的内容转换成 GBK 编码的内容: 可以通过以下的方式来实现: ```python import codecs # 打开 UTF-8 编码的文件 with codecs.open('utf8.txt', 'r', 'utf-8') as f: utf8_content = f.read() # 将 UTF-8 编码的内容转换成 GBK 编码的内容 gbk_content = utf8_content.encode('gbk') # 将 GBK 编码的内容写入文件 with codecs.open('gbk.txt', 'w', 'gbk') as f: f.write(gbk_content.decode('gbk')) ``` 希望这些信息能够帮助到你。如果你还有其他的问题,可以继续问我。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值