ASCII,Unicode,GBK和UTF-8字符编码的区别和联系

如果经常写python2,肯定会遇到各种“奇怪”的字符编码问题,每次都通过谷歌解决了,但是为什么会造成这种乱码、decode/encode失败等等,本文就字符和字符编码做一个总结,更加清晰区分诸多的编码。

字符集

一个系统支持的所有抽象字符的集合。字符是文字和符号的总称,包含各个国家文字、标点符号、图像符号、数字等。它为每一个字符分配一个唯一的ID,一般称之为码位、码点。

字符编码

它是一套规则,使用该规则能够将自然语言的字符的一个集合与其他东西的一个集合进行配对,在符号集合和数字系统中建立映射联系。在计算机中,处理信息是利用元件不同状态组合来存储和处理信息的,因此,字符编码就是将符号转化为计算机可以接受的数字系统的数,称为数字代码。它将上面字符集的码位转化为字节序列的规则,此过程称之为编码、解码。

常见字符集

ASCII字符集,GB2312字符集、Unicode字符集等。计算机需要准确处理各种字符集文字,需要进行字符编码,以便能够识别和存储各种文字。

常见字符编码

UTF编码

ASCII码

在计算机内部,所有信息最终都是一个二进制值。每一个二进制位(bit),有0和1两种状态,因此,8个二进制位可以组合出256种状态,这被称为字节(byte)。上个世纪60年代,美国制定了一套字符编码,对英文字符与二进制之间做了联系,这被称为ASCII码,一直沿用至今。

ASCII码一共规定了128个字符,比如SPACE是32,A是65,这128个符号只咱用了一个字节的后面七位,最前面的一位统一规定为0。

非ASCII码

英语用128个符号编码足够了,但是用来表示其他语言显然是不够的,于是,欧洲有些国家利用字节中闲置的最高位编入了新的符号,这样一来,欧洲国家使用的编码体系,可以最多表示256个字符。

但是到了亚洲国家,使用的符号更多了,光汉字就10万多个,一个字节只能表示256种符号,肯定是不够的,就必须使用多个字节表达一个符号。比如常见的GB2312编码,使用两个字节表示一个汉字,所以理论上最多可以表示256*256=65536个符号。

GBK码

GBK编码是对GB2312的扩展,完全兼容GB2312。采用双字节编码方案,剔出xx7F码位,共23940个码位,共收录汉字和图形符号21886个,GBK编码方案于1995年12月15日发布。它几乎完美支持汉字,因此经常会遇见GBK与Unicode的转换。

Unicode码

如上文所述,世界上有多种编码方法,同一个二进制数字可以被解释称不同的符号。因此,在打开一个文本文件时候,就必须知道它的编码方式,用错误的编码方式打开,就会出现乱码。

假如,有一种编码,将世界上所有的符号都纳入其中,每一种符号都给予独一无二的编码,那么乱码问题就不会存在了。因此,产生了Unicode编码,这是一种所有符号的编码。

Unicode显然是一个巨大的集合,现在的规模可以容纳100多万个符号。每个符号的编码都不一样,比如U+0041表示英语的大写字母A,U+4e25表示汉字严。

在Unicode庞大的字符集的优势下,还存在一个问题,比如一个汉字,“严”的Unicode是十六进制4e25,转成二进制足足有15位,也就是,这个符号需要2个字节,表示其他字符还存在3个字节或者更多。计算机怎么区别三个字节表示的是同一个符号而不是分开表示三个呢?如果Unicode统一规定,每个符号用3个字节表示,但是某些字母显然不需要3个,那么就浪费了空间,文本文件大小超出了很多,这显然是不合理的。直到UTF8字符编码出现了。

UTF8字符编码

随着互联网的发展,强烈要求出现一种统一的编码方式。UTF8就是在互联网中使用最多的对Unicode的实现方式。还有其他实现,比如UTF16(字符用2个字节或者4个字节表示),UTF32(字符用4个字节表示)。UTF8是Unicode的实现方式之一,也是最为常见的实现方式。

UTF8的最大特点是,它是一种变长编码,可以使用1-4个字节表示一个符号,根据不同的符号来变化字节长度。

UTF8编码规则只有两条:

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

2)对于非单字节(假设字节长度为N)的符号,第一个字节的前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

举个例子,以汉字“严”为例,它的Unicode是4e25(100111000100101),对应上表,处于第三行,因此严的UTF8编码需要3个字节。然后,从严的最后一个二进制位开始,从后向前填入X,多出的位补0,就可以计算出 11100100 10111000 10100101,转成十六进制就是E4B8A5。

Unicode与UTF8之间转换

严的Unicode编码是4e25,UTF8是E4B8A5,两者是不一样的,可以通过程序实现转码。

在Windows下有记事本小程序notepad.exe,打开文件后可以通过另存为,选择编码格式,重新保存新的文本文件。支持ANSI,Unicode,Unicde big endlian和UTF8。

1)ANSI是记事本默认编码方式,对于简体中文是GB2312。正是因为这个,Python读取文本文件时候一定要小心它的编码类型,因为不能直观到文本文件的格式。

2)Unicode编码这里使用UCS-2编码方式,采用两个字节存入字符的Unicode编码。

Python编码为什么如此蛋疼

总结了几种编码和编码规则,但是在Python2中编码问题就像幽灵一样困扰着开发者,其根本解决办法是理解清楚python2在内存中的字符存在的编码格式,在程序代码中始终采用Unicode编码处理,只有在输出时候才做encode处理。核心思想是:保证Python运行过程中字符编码格式是unicode编码,在任何地方。关于Python乱码问题,会在专门文章做分析,这里提供一个链接供参考。

Python编码为什么那么蛋疼?

编码探测

使用 chardet 可以很方便的实现字符串/文件的编码检测。尤其是中文网页,有的页面使用GBK/GB2312,有的使用UTF8,使用chardet基本可以探测出编码格式。

延伸阅读

谈谈Unicode编码

原文地址:https://www.cnblogs.com/geons/p/9352256.html

时间: 2024-11-03 21:11:50

ASCII,Unicode,GBK和UTF-8字符编码的区别和联系的相关文章

UTF-8、GBK、GBK2312等字符编码的区别和vim乱码等相关问题研究。

转自本人博客:xge技术博客 http://www.xgezhang.com/char_encodind_vim.html 关于字符编码的问题在做项目的时候经常都会出现,但一直没有很系统的研究过,今天早上系统的看了几篇文章.在此整理分享以下. 三种编码方式的简介: gb2312(又称为GB 2312-80)编码是一个简体中文字符集的中国国家标准,全称为<信息交换用汉字编码字符集·基本集>,又称为GB0,由中国国家标准总局发布,1981年5月1日实施.GB2312编码适用于汉字处理.汉字通信等系

ASCII,Unicode,GBK和UTF-8字符编码的区别联系

ASCII,Unicode,GBK和UTF-8字符编码的区别联系 wyrssktzc11级分类:其他被浏览86次2016.05.27 检举 KingSta逍遥 采纳率:45%7级2016.05.27 ASCII.Unicode.GBK和UTF-8字符编码的区别联系 很久很久以前,有一群人,他们决定用8个可以开合的晶体管来组合成不同的状态,以表示世界上的万物.他们看到8个开关状态是好的,于是他们把这称为"字节".再后来,他们又做了一些可以处理这些字节的机器,机器开动了,可以用字节来组合出

Python2和3字符编码的区别

Python2和3字符编码的区别 一.字符编码应用之Pyhton 1.1执行Python程序的三个阶段 test.py文件内容以gbk格式保存的,内容为: 阶段一:启动Python解释器 阶段二:Python解释器此时就是一个文本编辑器,负责打开文件test.py,即从硬盘中读取test.py的内容到内存中 此时,Python解释器会读取test.py的第一行内容,#coding:utf-8或#-*-coding:utf-8-*-,以此决定以什么编码格式将代码读入内存,这一行就是设定Python

ASCII、Unicode、GBK和UTF-8字符编码的区别联系

转自:http://my.oschina.net/u/658658/blog/411834?p={{currentPage+1}} 很久很久以前,有一群人,他们决定用8个可以开合的晶体管来组合成不同的状态,以表示世界上的万物.他们看到8个开关状态是好的,于是他们把这称为”字节“.再后来,他们又做了一些可以处理这些字节的机器,机器开动了,可以用字节来组合出很多状态,状态开始变来变去.他们看到这样是好的,于是它们就这机器称为”计算机“. 开始计算机只在美国用.八位的字节一共可以组合出256(2的8次

字符集和字符编码的区别

转自:https://www.cnblogs.com/xdyixia/p/9114145.html 1.字符,字符集,字符编码概念 字符:在计算机和电信技术中,一个字符是一个单位的字形.类字形单位或符号的基本信息.即一个字符可以是一个中文汉字.一个英文字母.一个阿拉伯数字.一个标点符号等. 字符集:多个字符的集合.例如GB2312是中国国家标准的简体中文字符集,GB2312收录简化汉字(6763个)及一般符号.序号.数字.拉丁字母.日文假名.希腊字母.俄文字母.汉语拼音符号.汉语注音字母,共 7

字符编码的区别与介绍

8位一个字节,1字节=1bytes 字符编码的发展史: ASCII码:255个字符,每个字符只占1bytes >> 1980年: GB2312,7000多个汉字 >>1995年:GBK1.0,20000多个汉字 >>2000年:GB18030,27000多个汉字 >>90年代,出现Unicode(万国码,统一码,单一码),每个字符占2bytes >>utf-8:Unicode的扩展集.en:2bytes:zh:3bytes python3里面默认

PYTHON 之 字符编码的区别与介绍

理解字符编码的历史与使用原因 1.计算机只能认0与1.2.通过0与1,二进制数,计算机能很容易识别出各种数字.3.为了能让计算机识别各种字符,美国人制定了ASCII码,能识别出127种字母与特殊字符,只需使用一个字节.3.因为ASCII码不支持中文,在1980设计出gb2312 ,收录了7445个汉字.4.到了1995年 设计出BGK1.0 收录了2万多个汉字.5.到了2000年,设置出GB18030 收录了2万7千多个汉字.6.到了不个不知道什么年份的时候,国际组织为了统一全世界的字符,设置出

ASCII、GBK、Unicode和UTF-8字符编码的区别联系

很久很久以前,有一群人,他们决定用8个可以开合的晶体管来组合成不同的状态,以表示世界上的万物.他们看到8个开关状态是好的,于是他们把这称为”字节“.再后来,他们又做了一些可以处理这些字节的机器,机器开动了,可以用字节来组合出很多状态,状态开始变来变去.他们看到这样是好的,于是它们就这机器称为”计算机“. 开始计算机只在美国用.八位的字节一共可以组合出256(2的8次方)种不同的状态. 他们把其中的编号从0开始的32种状态分别规定了特殊的用途,一但终端.打印机遇上约定好的这些字节被传过来时,就要做

ASCII、Unicode、GBK和UTF-8字符编码的区别与联系

很久很久以前,有一群人,他们决定用8个可以开合的晶体管来组合成不同的状态,以表示世界上的万物.他们看到8个开关状态是好的,于是他们把这称为”字节“.再后来,他们又做了一些可以处理这些字节的机器,机器开动了,可以用字节来组合出很多状态,状态开始变来变去.他们看到这样是好的,于是它们就这机器称为”计算机“. 开始计算机只在美国用.八位的字节一共可以组合出256(2的8次方)种不同的状态. 他们把其中的编号从0开始的32种状态分别规定了特殊的用途,一但终端.打印机遇上约定好的这些字节被传过来时,就要做