一文搞懂ASCII、Unicode与UTF-8

news2024/9/20 9:18:42

目录

  • 一、前置知识
  • 二、ASCII
  • 三、从ASCII到Unicode
  • 四、Unicode
  • 五、UTF-8
  • 六、总结
  • References

一、前置知识

  • 一个字节有8-bit;
  • 一个十六进制数占4-bit,故一个字节可以表示为两个十六进制数(通常会加上 0x 前缀);
  • 十六进制通常用来简化二进制的表示,例如 10101100 可以表示为 AC(可以通过在Python中执行 hex(0b10101100) 来验证)。

二、ASCII

ASCII(/ˈæski/,American Standard Code for Information Interchange,美国信息交换标准代码)是一个字符编码系统,用于在计算机和其他设备中表示文本。该系统最初由美国标准协会(ASA,现为ANSI)在1963年制定,并在后续几年中进行了几次修改和扩展。

ASCII编码使用7位二进制数(即0到127,共128个)来表示大部分英文标点符号、数字和大小写字母。例如,大写字母“A”的ASCII编码是65,小写字母“a”的ASCII编码是97。

ASCII表包含以下部分:

  • 控制字符(0-31和127,共33个):这些字符主要用于控制设备,如换行(10)和回车(13)。
  • 标准可见字符(32-126,共95个):包括数字(48-57)、大写字母(65-90)、小写字母(97-122)和各种标点符号。

一个标准的ASCII字符只占用一个字节(只使用了其中的7位),对于早期的计算机系统,这已经足够了,因为当时的计算机主要使用英语,并且对于其他语言的支持并不是一个主要关注点。然而,随着计算机技术的普及和国际化,这种仅限于128个字符的系统很快就显得不够用了。许多非英语的语言,包括欧洲的许多语言,都有一些ASCII无法表示的特殊字符。此外,还有一些常见的符号,例如货币符号,也无法用ASCII表示。

此时,一种解决方案是使用完整的8位字节来编码字符,从而可以表示256个不同的字符。这就是所谓的扩展ASCII,它提供了额外的128个字符来表示各种特殊字符和符号。

三、从ASCII到Unicode

ASCII编码主要支持英语,但对于包含非拉丁字符的其他语言(如中文、阿拉伯语、希腊语等)无法进行表示。这个局限性促使人们寻找新的编码方案,以便支持更多的字符集。

在中国,针对中文字符,人们开发了一系列的国标码(GB,即国家标准),包括GB2312、GBK和GB18030。

  • GB2312:这是中国在1980年代制定的编码标准,包括了全部的6763个简体中文汉字和682个其他语言字符。GB2312是双字节编码,使用两个字节来表示一个字符。所以理论上,GB2312可以表示65536(=2^16)个字符,但实际上并未全部使用。

  • GBK:全名《汉字内码扩展规范》。GBK是在GB2312基础上的扩展,包含了21003个汉字和883个图形符号。GBK的字节编码与GB2312相容,也是双字节编码,因此旧有的GB2312文档可以在GBK编码的处理器中打开,不会出现乱码。

  • GB18030:是GBK的进一步扩展,于2000年由中国国家标准总局发布。GB18030相较于GBK包含更多的字符,它覆盖了Unicode 11.0版本的所有字符。GB18030包含单字节、双字节和四字节字符,增加了对繁体字和少数民族文字的支持,是一个多字节编码。

然而,这些编码标准仍然存在局限性。首先,这些编码主要针对中国,对于其他语言的支持有限。其次,由于每个国家可能都有自己的编码标准(如日文的Shift_JIS,韩文的EUC-KR),这就导致了一个问题:同一个字符在不同字符集下的字符代码不同,而且往往一个字符集无法包含另一个字符集的所有字符,因此跨语言交流时往往会出现乱码。

为了解决这个问题,Unicode(统一码、万国码)被提出并得到广泛接受。Unicode是一种在全球范围内统一、唯一的字符集,它包括几乎所有的写作系统的字符。这就使得不同语言和不同国家的计算机系统可以使用同一种编码标准,从而简化了国际化软件的开发和支持。

四、Unicode

简单来讲,Unicode是一个字符集,它收录了世界上几乎所有的字符,并给每个字符分配了一个唯一的ID,这个ID就被称为码位(Code Point)。

Unicode码位是一个整数,范围是从0到1114111(十进制)或从0x0到0x10FFFF(十六进制)。这意味着Unicode标准理论上可以包含超过110万个不同的字符。然而,需要注意的是并非所有的码位都已经被分配给字符,目前只分配了约15万个。

码位一般会用十六进制数表示,并在前面加上 U+ 前缀。例如,字母A的码位是 U+0041,中文汉字「中」的码位是 U+4E2DPython 3中的字符默认是Unicode字符,这意味着Python 3中的字符可以表示几乎所有语言的字符。在Python中查找一个字符的码位仅需执行 hex(ord('A'))

📝 可以发现,Python中 chr() 函数能够接受的参数范围就是0到1114111,该函数接收一个码位并将其转化成对应的Unicode字符。

Unicode标准把码位分成了17个「平面」,每个平面包含65536个码位。第一个平面,从0x0000到0xFFFF,被称为基本多语言平面(Basic Multilingual Plane,简称BMP,几乎包含了现代语言的所有字符),剩余16个是辅助平面,因此Unicode总共有17 × 65536 = 1114112个码位。

除了使用 chr() 来获得码位对应的Unicode字符,我们还可以使用转义序列 \u\U。具体来说:

  • \u 后面跟四个十六进制数字,表示一个Unicode字符。例如,\u03B1 表示希腊字母"α"。
  • \U 后面跟八个十六进制数字,用于表示超出基本多语言平面的Unicode字符。也就是说,它能表示的Unicode字符的范围更广。

例如:

print('\u03B1')  # 输出:α,等价于chr(0x03b1)
print('\U0001F604')  # 输出:😄,等价于chr(0x1f604)

\U 后面需要跟八个数字,即使前面的数字是0。如果一个字符可以用 \u 来表示,通常会优先使用 \u,因为它更简短。

五、UTF-8

前面提到过,Unicode仅仅是一个字符集,它为每个字符分配了一个唯一的编号,但却没有规定这些编号应当如何存储。

例如,字母A的码位是 U+0041,至少需要用一个字节来存储;汉字「中」的码位是 U+4E2D,至少需要用两个字节来存储;表情「😃」的码位是 U+1F603,至少需要用三个字节来存储。这就导致一个严重的问题:计算机怎么知道三个字节表示一个字符,而不是分别表示三个字符呢?

一个简单粗暴的做法是,我们为每个Unicode码位都分配四个字节,这意味着每个字符都用相同数量的字节表示。这便是UTF-32。

📝 即使是 U+10FFFF 也只需要三个字节就够了,至于为什么不统一分配三个字节,是因为计算机读取 2 i 2^i 2i 个字节的效率更高。

UTF-32(32-bit Unicode Transformation Format)是一种Unicode字符编码方案,它使用32位(4字节)来表示每个字符。可以看出,它是一种定长编码方案。

UTF-32的编码方式非常直观和简单,每个字符使用固定的4字节进行表示。例如,字母A的UTF-32表示为 00000041,同样,汉字「中」的UTF-32表示为 00004E2D(这里采用的是Big Endian,即UTF-32BE)。

可以发现,在UTF-32编码中,ASCII字符也需要使用4个字节来编码,这与其只需要使用1个字节来编码的ASCII字符集本身相比,造成了空间的大量浪费。为解决这一问题,UTF-16考虑使用两个字节来表示BMP(U+0000-U+FFFF),用四个字节来表示剩余的辅助平面(U+10000-U+10FFFF)。

⚠️ 实际上UTF-16还会涉及到高位代理(High Surrogate)和低位代理(Low Surrogate),这里不再赘述。

UTF-8是一个变长的编码方案,它使用一到四个字节来表示不同的字符,具体方案如下:

  • U+0000 - U+007F:采用一个字节;
  • U+0080 - U+07FF:采用两个字节;
  • U+0800 - U+FFFF:采用三个字节;
  • U+10000 - U+10FFFF:采用四个字节。

不过一个问题在于,给定一个字节序列,由于UTF-8是变长的,我们怎么得知第一个字符占用了多少字节呢?

这里就要用到自同步(Self-synchronization)的概念了。自同步是指,在字符编码的上下文中,能从字节流的任意位置开始读取,并能正确地确定字符的边界,无需回溯到字节流的开始处。

UTF-8编码就是一种自同步编码方式,它的设计允许在任何字节序列中定位字节边界:

  • 如果一个字节的最高位是0,那么这个字节就是一个ASCII字符,即这个字节代表一个字符;
  • 如果一个字节的最高位是1,那么这个字节就是一个多字节字符的一部分。连续的1的数量表示了这个多字节字符的总字节数。例如,如果一个字节的前两位是11,那么这就是一个多字节字符的开始,且这个字符总共有两个字节;如果一个字节的前三位是111,那么这就是一个多字节字符的开始,且这个字符总共有三个字节;
  • 如果一个字节的前两位是10,那么这就是一个多字节字符的中间字节

可以看出UTF-8兼容ASCII字符集,因此在处理纯ASCII文本时,UTF-8编码和ASCII编码是一样的,每个字符都只需要一个字节。

UTF-8的二进制格式列在下表中:

码位范围二进制格式
U+0000 - U+007F0XXXXXXX
U+0080 - U+07FF110XXXXX 10XXXXXX
U+0800 - U+FFFF1110XXXX 10XXXXXX 10XXXXXX
U+10000 - U+10FFFF11110XXX 10XXXXXX 10XXXXXX 10XXXXXX

那么给定一个Unicode字符,我们如何计算它的UTF-8编码呢?

例如对于汉字「严」,执行 hex(ord('严')) 可得知它的码位是 U+4E25,根据上表,该字的UTF-8编码需要三个字节,即格式是 1110XXXX 10XXXXXX 10XXXXXX,接下来进行填空。执行 bin(ord('严')) 可得知「严」的二进制为 100111000100101,按照上述空缺处进行分组可得到 100 111000 100101,填入后得到 1110X100 10111000 10100101,剩下的 X 用0填充,于是就得到了「严」的UTF-8编码 11100100 10111000 10100101,转换成十六进制就是 E4B8A5

可以通过在Python中运行如下代码来直接获得「严」的UTF-8编码:

print('严'.encode('utf-8'))

Python 3使用的编码标准就是UTF-8,在命令行执行如下命令来查看默认编码:

python -c "import sys; print(sys.getdefaultencoding())"

六、总结

Unicode是字符集,而UTF-32、UTF-16、UTF-8是Unicode的一种编码方案(实现方式),旨在将码位转换成可以存储和传输的字节序列。


References

[1] https://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html
[2] https://blog.csdn.net/qq_36761831/article/details/82291166
[3] https://www.zhihu.com/question/23374078/answer/24385963
[4] https://zhuanlan.zhihu.com/p/51828216
[5] https://docs.python.org/zh-cn/3/howto/unicode.html#

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/691267.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于Python+OpenCV的视频字符化(深度学习+机器视觉)含全部工程源码

目录 前言总体设计系统整体结构图系统流程图 运行环境Python 环境OpenCV环境 模块实现1. 视频读取及处理2. 色素块识别与替换3. 视频合成4. 操作系统上的实现 系统测试工程源代码下载其它资料下载 前言 本项目利用 OpenCV 提供的轻量、高效的 C类和 Python 接口,实…

数据平台流量回放最佳实践|精选

1.1 数据平台业务背景 数据平台利用大数据智能分析、数据可视化等技术,对公司内外部经过采集、建设、管理、分析的多源异构数据进行呈现和应用,实现了数据共享、日常报表自动生成、快速和智能分析,深度挖掘数据价值,满足企业各级…

Leetcode48 旋转图像

给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在 原地 旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 示例 1: 输入:matrix [[1,2,3],[4,5,6],[7,8,9]] 输出…

ZYNQ——按键消抖实验

文章目录 原理简介软件仿真板上验证 原理简介 按键作为基本的人机输入接口,在很多电子设计中都是比较常见的,但是由于其机械特性,在按键按下或者松开的时候,按键的输入值是有抖动的。按键的抖动是其固有特性,因此无论…

打死也不要进外包,来看看我在腾讯外包的这2年......

我18年毕业于一个普通二本学校,是一个很不出名的小本科。大学期间专业知识也没有去认真的学习,所以毕业的时候就随便找了一份工作,在一个小公司做功能测试。 记得那时候薪资大概是6k左右,因为是在工厂,工作环境很差&a…

Gitlab 访问令牌更新 替换

引言 访问令牌到期后如何丝滑更换,或则如何更改账户的访问令牌实现权限变动呢?在我们使用访问令牌克隆项目之后,Windows凭据就帮我们记录下了密码。当然密码是不可见的,只能进行删除重新设置,通过凭据管理器进行更改。…

python基于预训练大模型权重实现文本向量化开发构建微博评论数据情感极向识别模型

因为最近的一些项目涉及到了大模型相关的技术开发研究,在我前面的博文中也已经有一些实践记录学习资料分享的文章了,今天是在做模型训练的时候突然想到一个有意思的想法,按照我之前做文本分类的方法,基本主流的技术路线都是先对文…

性能提升571%,32K超长上下文,推理速度提升42%,允许商用,国产开源大模型推出了二代 ChatGLM2-6B...

6月份是火热的夏天,各种火热的 AI 产品也在密集的更新,天越热,大家是干得热火朝天,卷出了新高度。 前有现在大火的 ChatGPT,ChatGPT 更新:大杀器!函数调用示范,ChatGPT 3.5/4 双双升…

Java Web JDBC(2)23.6.26

3.6 PreparedStatement PreparedStatement作用: 预编译SQL语句并执行:预防SQL注入问题 3.6.1 代码模拟SQL注入问题 Test public void testLogin() throws Exception {//2. 获取连接:如果连接的是本机mysql并且端口是默认的 3306 可以简化书…

浅谈无线温度监测系统在冶炼厂供配电的应用

安科瑞 华楠 摘要:高压供配电系统运行稳定性与电气元器件连接点温度密切相关,通过与传统测温方法对比,实时在线无线温度监测解决 了密封高压开关柜内部各连接点温度无法检测的难题,满足了供电系统安全稳定运行的要求,降…

redis 主从复制 哨兵 安装部署

学习开始前先了解一下 Redis是一个开源的内存数据结构存储系统,它支持多种数据结构,如字符串、哈希表、列表、集合、有序集合等。Redis最大的特点是数据存储在内存中,因此读写速度非常快,同时也支持数据持久化,可以将数…

吐血整理,接口自动化测试-Config配置文件框架封装(实战)

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 configparser的介…

阿里巴巴2023最新版Spring Security王者晋级文档

Spring 是一个非常流行和成功的 Java 应用开发框架。Spring Security 是 Spring 家族中的一个安全管理框架,提供了一套 Web 应用安全性的完整解决方案。在用户认证方面,Spring Security 框架支持主流的认证方式,包括 HTTP 基本认证、HTTP 表单…

输出一个数的十六进制表示

可以使用Integer.toHexString、Long.toHexString得到数值的十六进制表示。 下面的代码示例列出了几种情况: public class Test5 {public static void main(String[] args) {byte b1 0b01101111; System.out.println(Integer.toHexString(b1).toUpperCase());byte…

深度学习的实践层面

目录 1、训练、验证、测试集 2、偏差、方差 3、正则化 4、dropoout正则化 5、其他正则化方法 6、归一化输入 7、梯度消失和梯度爆炸 8、梯度的数值逼近 9、梯度检验 1、训练、验证、测试集 (1)、早期机器学习领域普遍认可的最好的实践方法&…

海兰一体机电脑U盘重装Win10系统教程图解

海兰一体机电脑是全家人都适用的电脑,使用海兰一体机电脑的用户要怎么用U盘来重装Win10系统,首先用户需要确保电脑能够正常联网,然后再准备一个8G以上的U盘,最后根据小编分享的海兰一体机电脑U盘重装Win10系统教程图解操作即可。 …

PR脚本:音乐鼓点自动节拍打点标记动画BeatEdit

BeatEdit可检测音乐中的节拍并在Premiere Pro时间轴中为其生成标记。可以创建与音乐同步的自动编辑,或者让BeatEdit v2.0.006 激活版协助您进行手动编辑过程。BeatEdit mac版使用节拍信息来生成与音乐同步的全自动编辑。如果需要更多控制,拍子标记也可以…

视唱音准不好的人能练好吗,视唱音准不好怎么办

软件版本:Earmaster7.3.6 无论是普通人还是声乐艺术生,音准是唱好歌的必要条件之一,如果音准不好,唱歌自然会跑调。然而并不是所有人天生都有十分出色的音准,如果不进行后天的训练,是很难找到正确的音准的…

web应用封装成app|超级签名

PP封装是形成APP的最省钱的一种方式。你只需要拥有一个网址就可以通过一些技术处理封装成一个跨iOS和Android的APP,这个过程往往只需要几分钟。在移动互联网时代,拥有一个移动端APP是必不可少的。那么APP是怎样封装的呢? 首先让我们先来了解…

基于深度学习的人脸面部表情识别系统【含Python源码+PyqtUI界面+原理详解】

功能演示 摘要:面部表情识别(Facial Expression Recognition)是一种通过技术手段识别人物图像中人脸面部表情的技术。本文详细介绍了其实现的技术原理,同时给出完整的Python实现代码、训练好的深度学习模型,并且通过Py…