字符编码 简介

一、计算机基础之——交互

​ 操作系统、计算机硬件、应用程序组成了计算机系统。我们在使用计算机系统处理任务时其实就是让计算机系统的各个组成之间进行一系列复杂的交互处理,得到我们想要的结果。计算机硬件各组成之间的交互是通过二进制指令代码进行的,但我们在使用电脑时,几乎所有可视的文本文件都是以人类常用的语言字符呈现的,那么计算机系统是如何将人类语言字符转换成二进制代码的呢。

​ 当我们使用使用文本编辑器时,计算机系统是如何实现文件内容的的保存和读取的呢。

二、文本编辑器存取文件的原理

1、当我们打开一个文本编辑器,就在内存中开启了一个进程,之后,我们在其中编写的内容也是存放在内存中的。此时的数据断电即丢失。

2、当我们按下保存后,这些数据就被保存到了硬盘上,实现永久保存。

3、同理,我们编写的代码文件也是一样,在执行前都是以文本形式存在的。对于计算机来说都是一堆字符而已。

三、Python解释器执行py文件的原理

第一步:打开python解释器,此时就相当于打开了一个文本编辑器

第二步:python解释器相当于文本编辑器去打开py文件,从硬盘将文件内容读取到内存中(这一步只取内容,不判断内容是否正确)

第三步:点击运行后,python解释器才开始解释并执行代码(解释一行执行一行,解释时判断语法,执行时才会给变量开辟内存空间)

四、python解释器与文本编辑器的异同

相同点:都能够将文本内容读入内存,都能够编辑和保存。

不同点:文本编辑器只对文件内容操作,而python解释器除了能对文件内容操作,还能理解内容、判断语法、执行代码

五、字符编码

1、什么是字符编码

字符编码就是将某种文字和字符按照一定的规则编译成一一对应的代码。

2、为什么要对字符进行编码

因为计算机只认识0和1,人类要让计算机理解人类的意图就必须把人类常用的高级语言字符编译成计算机能识别的代码。

​ 字符 ——> 编译规则(编码表) ——> 二进制代码

3、字符编码发展史和分类

1、ASCII

在计算机中,所有的数据在存储和运算时都要使用二进制数表示(因为计算机用高电平和低电平分别表示1和0),例如,像a、b、c、d这样的52个字母(包括大写)以及0、1等数字还有一些常用的符号(例如*、#、@等)在计算机中存储时也要使用二进制来表示,而具体用哪些二进制数字表示哪个符号,当然每个人都可以约定自己的一套规则(这就叫编码表),而大家如果要想互相通信而不造成混乱,那么大家就必须使用相同的编码规则,于是美国有关的标准化组织就统一规定了英语字母和常用符号用哪些二进制数来表示,并于1967年发表了第一版ASCII,最后一次更新则是在1986年,到目前为止共定义了128个字符。比如空格SPACE是32(二进制00100000),大写的字母A是65(二进制01000001)。这128个符号(包括32个不能打印出来的控制符号),只占用了一个字节的后面7位,最前面的一位统一规定为0。

2、其他国家的编码表

英语用128个符号编码就够了,但是对于其他语言,128个符号就不一定够了。随着各国的计算机行业的发展,各国陆续推出了自己国家的编码表。比如中国的GBK,日本的shift_JIS,韩国的Euc-kr,等等,都是对应二进制代码的。这样,不同国家之间数据交流就出现了问题,相同的二进制代码在两种编码中表示不一样的字符,或者同样的字符在两种编码中用了不同的二进制代码。用A国的编码规则编码的文件拿到B国的电脑上就不能正确打开了(乱码),不利于沟通交流。

随着全球化的发展,世界急需统一的编码来实现信息的顺畅流通,因此,号称万国码的Unicode就应运而生了。

3、Unicode

号称万国码的Unicode包含了全球主要国家的字符编码,至此,不同国家的人们终于可以一起在互联网的世界愉快的玩耍啦。但是,很快又有人提出了不满。因为Unicode 是一个很大的集合,现在的规模可以容纳100多万个符号。每个符号的编码都不一样,比如,U+0639表示阿拉伯字母AinU+0041表示英语的大写字母AU+4E25表示汉字。有的字符原来只要一个字节表示,有的字节需要三、四个字节表示,这么多的字符不分类岂不乱套了,好嘛,将字符编码的格式做了统一,都用四个字节吧,多余的位用0补位。

这样就造成了两个问题:

(1)、有的文件原来只需要1mb的空间就够了,按照Unicode却需要4mb的空间,及其浪费。因此呢,他们不干了,各种消极应对,各种抵制(尤其是某老喜欢横着走的国家)。导致Unicode 在很长一段时间内无法推广,直到互联网的出现。

(2)、出现了 Unicode 的多种存储方式,也就是说有许多种不同的二进制格式,可以用来表示 Unicode。

随着互联网的普及,喜欢玩儿耍的网友们就强烈要求出现一种统一的编码方式。在网友们欢快而激情的讨论中呢 UTF-8 就诞生了(同时还有utf-16、utf-32,但是对我们没啥niao用,都想不起来了)。至此,大家又可以一起愉快的玩耍了。

4、UTF-8

UTF-8 就是在互联网上使用最广的一种 Unicode 的实现方式。强调一下喔,这里的关键是,UTF-8 是 Unicode 的实现方式之一。

UTF-8 最大的一个特点,就是它是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。

UTF-8 的编码规则很简单,只有以下二条:

1)对于单字节的符号,字节的第一位设为0,后面7位为这个符号的 Unicode 码。因此对于英语字母,UTF-8 编码和 ASCII 码是相同的。

2)对于n字节的符号(n > 1),第一个字节的前n位都设为1,第n + 1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的 Unicode 码。

Unicode符号范围     |        UTF-8编码方式
(十六进制)        |              (二进制)
----------------------+---------------------------------------------
0000 0000-0000 007F | 0xxxxxxx
0000 0080-0000 07FF | 110xxxxx 10xxxxxx
0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

跟据上表,解读 UTF-8 编码非常简单。如果一个字节的第一位是0,则这个字节单独就是一个字符;如果第一位是1,则连续有多少个1,就表示当前字符占用多少个字节。

5、Unicode 与 UTF-8 之间的转换

二者的转换可以通过程序实现,当然,有些应用软件提供了多种编码模式的文件保存方法,可以一件转换。

6、内存为什么不直接用UTF-8呢?

有朋友又问了,UTF-8这么好,那我们为什么在内存中还要用Unicode呢,直接用UTF-8不行吗?

这是因为UTF-8 是 Unicode 的实现方式之一,只管编码存储,不管解码读取,所以,当你要从硬盘上读取岛国大片的时候呢,UTF-8 就不管用啦,还得要Unicode来解码才行。当然了,如果你非要厂家给你造一台内存也用UTF-8的电脑呢也行,只不过那样的话你就只能自己跟自己玩儿了。

当然了,你也可以一直等,因为据Allen的下预测呢,随着UTF-8 的发展呢,Unicode有可能越来越不被必须的,也许,在不久的将来,大家都用UTF-8啦。

7、乱码分析

首先明确概念

  • 文件从内存写到硬盘的操作简称存文件
  • 文件从硬盘读到内存的操作简称读文件

乱码的两种情况:

  • 乱码一:存文件时就已经乱码

存文件时,由于文件内容有各个国家的文字,我们单以一个国家的编码规则去存,
此时上其他国家的文字由于在此编码规则中没有找到对应的编码而导致存储失败。但当我们硬要存的时候,编辑并不会报错,但毫无疑问,不让存而硬存,肯定是乱存了,即存文件阶段就已经发生乱码,而当我们用此编码规则打开文件时,此国文字可以正常显示,而其他文字则乱码了。

  • 乱码二:存文件时不乱码而读文件时乱码

存文件时用utf-8编码,保证兼容万国,不会乱码,而读文件时选择了错误的解码方式,比如gbk,则在读阶段发生乱码,读阶段发生乱码是可以解决的,选对正确的解码方式就ok了。

六、总结和补充

ASCII和Unicode的区别:ASCII编码是1个字节,而Unicode编码通常多于1个字节。

字母A用ASCII编码是十进制的65,二进制的01000001;

字符0用ASCII编码是十进制的48,二进制的00110000,注意字符'0'和整数0是不同的;

如果把ASCII编码的A用Unicode编码,只需要在前面补0就可以,因此,A的Unicode编码是00000000 01000001。

问题:如果统一成Unicode编码,乱码问题解决了。但是,如果你写的文本基本上全部是英文的话,用Unicode编码比ASCII编码需要多一倍的存储空间,存储和传输都浪费。

解决措施:把Unicode编码转化为“可变长编码”的UTF-8编码。UTF-8编码把一个Unicode字符根据不同的数字大小编码成1-6个字节,常用的英文字母被编码成1个字节,汉字通常是3个字节,只有很生僻的字符才会被编码成4-6个字节。如果你要传输的文本包含大量英文字符,用UTF-8编码就能节省空间:

UTF-8编码有个好处,就是ASCII编码实际上可以被看成是UTF-8编码的一部分,所以,大量只支持ASCII编码的历史遗留软件可以在UTF-8编码下继续工作

计算机系统通用的字符编码工作方式:

在计算机内存中,统一使用Unicode编码,当需要保存到硬盘或者需要传输的时候,就转换为UTF-8编码。

启动记事本程序时,从文件读取的UTF-8字符被转换为Unicode字符到内存里,编辑完成后,保存的时候再把Unicode转换为UTF-8保存到文件:

浏览网页的时候,服务器会把动态生成的Unicode内容转换为UTF-8再传输到浏览器:

所以你看到很多网页的源码上会有类似 的信息,表示该网页正是用的UTF-8编码。

参考:

Nick 老师的博客:https://www.cnblogs.com/nickchen121/p/10718112.html

猜你喜欢

转载自www.cnblogs.com/allenchen168/p/11537105.html