计算机字符编码基础
一、计算机基础
二、文本编辑器存取文件的原理
1、打开编辑器就打开启动了一个进程,是在内存中,所以,用编辑器编写的内容也都是存放与内存中的,断电后数据丢失了。
2、要想永久保存,需要点击保存按钮:编辑器把内存的数据刷到硬盘上。
3、在外面编写一个.py文件(没有执行),跟编写其他的文件没有任何区别,都只是在编写一堆字符而已。
三、Python解释器执行py文件的原理
-
第一阶段:Python解释器启动,此时就相当于启动了一个文本编辑器。
-
第二阶段:Python解释器相当于文本编辑器,去打开test.py文件,从硬盘上将test.py的文件内容读入到内存中(小复习:Python的解释性,决定了解释器只关心文件内容,不关心文件后缀名)。
-
第三阶段:Python解释器解释执行刚刚加载到内容中的test.py的代码(ps:在该阶段,即真正执行代码时,才会识别Python的语法,执行文件内代码,当name=“egon”,会开辟内存空间存放字符串“egon”)。
四、Python解释器与文件本编辑的异同
-
相同点:Python解释器是解释文件内容的,因而Python解释器具备读py文件的功能,这一点与文本编辑器一样。
-
不同点:文本编辑器将文件内容读入内存后,是为了显示或者比编辑,根本不去理会python的文法,而Python解释器将文件内容读入内存后,可不是为了给你瞅一眼Python代码写的啥,而是为了执行Python代码、会识别Python语法。
五、字符编码介绍
5.1 什么是字符编码
计算机要想工作必须通电,即用‘电’驱动计算机干活,也就是说‘电’的特性决定了计算机的特性。电的特性即高低电平(人类从逻辑上将二进制数1对于了高电平,二进制数0对应低电平),关于磁特性也是同样的道理。结论:计算机只认识数字。
很明显,我们平时在使用计算机时,用的都是人类能读懂的字符(用高级语言编程的结果无非是在文件内一堆字符),如何能让计算机读懂人类的字符?
必须经过一个过程:
- 字符------>翻译过程-------->数字
总而言之,字符编码是将人类的字符编码程计算机能识别的数字,这种转换必须遵循一套规定的标准,该标准无非是人类字符与数字对应关系,称之为字符编码表。
5.2 涉及到字符编码的两个场景
1、一个Python文件中的内容是由一堆字符组成的,存取均涉及到字符编码问题(Python文件并未执行,前两个阶段均属于该范畴)。
2、Python中的数据类型字符串是由一串字符组成的(Python文件执行时,即第三个阶段)。
5.3 字符编码发展史与分类
计算机是由美国人发明的,最高的字符编码为ASCII,之规定了英文字母数字和一些特殊字符与数字的对应关系。最多只能用8位表示(一个字节),即28=256,所以ASCII码最多只能表示256个符号。
当然我们编程语言都用英文没问题,ASCII够用,但是处理数据时,不同的国家有不同的语言,中国人会加入中文,日本人会在自己的程序中加入日文,韩国人也是。
但是要表示中文,单拿一个字节表示一个汉字,是不可能表达完的(连小学生都认识两千多个汉字),解决方法只有一个,就是一个字节用>8位2进制代替,位数越多,代表的变化就多,这样,就可以尽可能多的表达出不同的汉字。
所以中国人规定了自己的标准GB2312编码,规定了包含中文在呢哦的字符与数字的对应关系。
日本日规定了自己的Shift——JIS编码,韩国人规定了自己的Euc-kr编码(另外,韩国人说,计算机是他们发明的,要求世界统一用韩国编码,但是世界人民没有搭理他们)。
这时候问题出现了,精通18国语言的小周同学谦虚的用8国语言些了一篇文档,那么这篇文档,按照哪国的标准,都会出现乱码(应为此刻的各种标准只是规定了自己国家的文字在哪的字符跟数字的对应关系,日过单纯采用一种国家的编码格式,那么其余国家的语言的文字在解析时就会出现乱码)。所以迫切需要一个世界的标准(能包含全世界的语言)于是Unicode应运而生(韩国人表示不服,然后没有什么卵用)。
acsii用1个字节(8位二进制)代表一个字符,Unicode常用2个字节(16位二进制)代表一个字符,生僻字需要4个字节。
- 例子:字母X,用ascii表示是十进制的120,二进制0111 1000.
汉字中已经超出了ASCII编码的范围了,用Unicode编码是十进制的20013,二进制的0100111000101101.字母x,用Unicode表示二进制0000 0000 0111 1000,所以Unicode兼容ascii,也兼容万国,是世界的标准。这时候乱码问题消失了,所有的文档我们都是用但是新问题出现了,如果我们的文档通篇都是英文,你用Unicode会比ascii耗费多一倍的空间,在存储和传输上十分的低效。
本着节约的精神,有出现了把Unicode编码转化成“可变长编码”的UTF-8(Unicode Transformation Format-8)编码。UTF-8编码是把一个Unicode字符根据不同的数字大小编码程1-6个字节,通常英文字母编码成1个字节,汉字通常都是3个字节,只有恨生僻的字符才会被编码成4-6个字节。如果你要传输的文本包含大量英文字符,用UTF-8编码就能节省空间
字符 | ASCII | Unicode | UTF-8 |
---|---|---|---|
A | 01000001 | 00000000 01000001 | 01000001 |
中 | x | 01001110 00101101 | 11100100 10111000 10101101 |
从上面的表格还可以发现,UTF-8编码有一个额外的好处,就是ASCII编码世纪上可以堪称是UTF-8编码的一部分,所以,大量只支持ASCII编码的历史遗留软件可以在UTF-8编码下继续工作。
5.4 内存为什么不用UTF-8呢?
说了那么一大堆,那为什么内存用Unicode,而不直接使用UTF-8呢?这样不就可以直接把代码从内存直接丢入硬盘了吗?出现这个问题的原因是硬盘中还躺了其他国家的代码,各个国家的代码的二进制还需要运行在计算机上使用,因此内存中必须使用Unicode的编码,因为Unicode能和硬盘中的其他国家二进制中的代码进行转换,但是UTF-8只是简化了代码的存储,它并不能与其他国家硬盘中的代码进行关系转换。总而言之只有Unicode编码才能运行其他国家硬盘中的代码,而UTF-8代码无法进行该操作。
内存中还使用Unicode编码,是因为历史遗留问题造成的,但是因为现在写代码使用的都是UTF-8代码,所以,以后内存中的代码都将变成UTF-8代码,并且以前遗留的各个国家的代码都将会被淘汰,所以未来内存中使用的编码也将使用UTF-8编码替代Unicode编码。
5.5字符编码之文本编辑器操作
5.6乱码分析
首先明确概念
-
文件从内存刷入到硬盘的操作简称存文件
-
文件从硬盘读到内存的操作简称读文件
乱码的两种情况
- 乱码一:存文件时就已经乱码了
存文件时,由于文件内有各个国家的文字,我们单以shiftjis去存,本质上其他国家的文字由于shiftjis中没有找到对应的关系而导致存储失败,但当我们硬要存的时候,编辑并不会报错(难道你的编码错误,编辑器这个软件就跟着崩溃了吗???),但毫无疑问,不能存而硬存,肯定是乱存了,即存文件阶段就已经发生了乱码,而当我们用shiftjis打开文件时,日文可以正常显示,而中文则乱码了。 - 乱码二:存文件时不乱码而读文件时乱码
存文件时用UTF-8编码,保证兼容万国,不会乱码,而读文件时选择了错误的解码方式,比如gbk,则在读阶段发生了乱码,读阶段发生了乱码时可以解决的,选对正确的解码方式就ok了。
六、总结
1、保证不乱码的核心法则就是,字符按照什么标准编码的,就要按照什么标准解码,此处的标准指的是字符编码。
2、在内存中写的所有字符,一视同仁,都是Unicode编码,比如我们打开编辑器,输入一个“你”,我们并不能说“你”就是一个汉字,此时它仅仅只是一个符号,该符号可能很多国家都在使用,根据我们使用的输入法不同这个字的样式可能也不大一样。只有我们往硬盘保存或者基于网络传输时,才能确定“你”到底是一个汉字,还是一个日本字,这就是Unicode转换成其他编码格式的过程了,简而言之,就是内存中固定使用的就是Unicode编码,我们唯一改变的就是存储到硬盘时使用的编码。
- Unicode-----> encode(编码)------>gbk
- Unicode<-------decode(解码)<-------gbk
原文地址:nikechen121字符编码博客