在python中,字符编码问题困扰着很多初学者,那么我们应该如何理解字符编码,做到心中“有谱”,能正确的处理字符呢?本文即是从这个需求出发,来帮助理解字符编码。按照惯例,先介绍相关的概念,再通过实例帮助理解。
字符是各种文字和符号的总称,包括各个国家文字、标点符号、图形符号、数字等。 字符集是多个字符的集合,字符集种类较多,每个字符集包含的字符个数不同,常见字符集有:ASCII字符集、GB2312字符集、BIG5字符集、GB18030字符集、Unicode字符集等 计算机要准确的“识别”并处理各种字符集文字,就需要按照相应的规则,对各种文字进行字符编码 字符编码(encoding)和字符集不同。字符集只是字符的集合,不一定都适合进行网络传送以及某些处理,有时须经编码(encode)后才能应用。 字符编码就是以二进制的数字映射字符集的字符。 因此,对字符进行编码,是信息交流的技术基础。 SBCS(single-Byte Chactacter System(Set)):单字节字符系统(集),表示在这种编码类型下,所有字符只用一个字节表示。 MBCS(Multi-Byte Chactacter System(Set)):多字节字符系统(集),表示在这种编码类型下,所有字符可以由一个或多个字节表示,实际几个字节要看使用的具体编码方案。 SBCS/MBCS 是编码的一种类型,而不是某个特定编码的名称。 我们知道计算机只能”认识” 0和1,那么计算机中存储介质(如,内存或硬盘)对信息的存储方式就是1和0。物理上,硬盘的盘片表面凹凸不平,凸起的地方被磁化,凹的地方是没有被磁化;凸起的地方代表数字1,凹的地方代表数字0。 任何文字要存储到计算机中,都需要先编码成相应的二进制数,然后再存储。双方进行数据通讯时,也要保证发送方和接收方的编码方式相同,否则也是鸡同鸭讲,就会出现我们遇到的乱码问题。 美国信息交换标准码,是基于拉丁字母的一套电脑编码系统,主要用于显示现代英语和其他西欧语言。等同于国际标准ISO/IEC 646,到目前为止共定义了128个字符。 字符集:从符号(NUL)到符号(DEL) 字符编码范围:二进制:00000000——01111111; 十进制:0-127 占用字节:1字节(8bit); 盘片储存方式:00000000 ——11111111 GB2312 是对 ASCII 的中文扩展,兼容ASCII,采用双字节编码。中文名称为:信息交换用汉字编码字符集 GB2312编码适用于汉字处理、汉字通信等系统之间的信息交换,通行于中国大陆;新加坡等地也采用此编码。中国大陆几乎所有的中文系统和国际化的软件都支持GB 2312。 基本集共收入汉字6763个和非汉字图形字符682个。整个字符集分成94个区,每区有94个位。每个区位上只有一个字符,因此可用所在的区和位来对汉字进行编码,称为区位码 (在线查询)。 区位码是一个四位的十进制数,它的前两位叫做区码,后两位叫做位码。 每个国标码或区位码都对应着一个唯一的汉字或符号。国标码是一个四位十六进制数,把换算成十六进制的区位码加上A0A0H,就得到国标码。一般我们看到的16进制显示的字符编码值就是国标码。区位码表 国标码和区位码的对应关系:国标码 = 区位码(16进制)+0xA0A0 下面举两个实际的例子,来说明国标码和区位码的具体转换,弄着这个原理后,以后就可以自己进行查表和计算,真正的”由表及里”。 通过查表得到: “啊”字 的区位码为1601(十进制) 区码和位码分别加上0xA0,就得到GB2312编码:1601 –> 0x1001–>0x1001+0xA0A0–>0xB0A1(gb2312编码查询) “汉” 字 的区位码为 2626(十进制) GB2312 编码值计算:2626 –> 0x1A1A –> 0x1A1A + 0xA0A0 –>BABA GBK 兼容ASCLL 兼容 GB2312, 是GB2312的扩展。 中文全称:汉字内码扩展规范 英文名称:Chinese Internal Code Specification GBK编码,是在GB2312-80标准基础上的内码扩展规范,使用了双字节编码方案,其编码范围从0x8140至0xFEFE(剔除xx7F),共23940个码位,共收录了21003个汉字,完全兼容GB2312-80标准,支持国际标准ISO/IEC10646-1和国家标准GB13000-1中的全部中日韩汉字,并包含了BIG5编码中的所有汉字。GBK编码方案于1995年10月制定, 1995年12月正式发布,中文版的WIN95、WIN98、WINDOWS NT以及WINDOWS 2000、WINDOWS XP、WIN 7等都支持GBK编码方案。 Unicode(统一码、万国码、单一码)是计算机科学领域里的一项业界标准,包括字符集、编码方案等。Unicode 是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码。目的就是为了将全世界所有文字都收录到一个统一的字符集,以满足跨语言、跨平台进行文本转换、处理的要求。1990年开始研发,1994年正式公布。 Unicode为世界上所有字符都分配了一个唯一的数字编号,分为17组编排,这个编号范围从 0x000000 到 0x10FFFF(21位),每组称为平面(plane),每个plane有65536个码位,共有65536*17=1114112个,每个字符都有一个唯一的Unicode编号,这个编号一般写成16进制,在前面加上U+。例如:“马”的Unicode是U+9A6C。Unicode 只是一个字符集,它只规定了字符的编号,却没有规定这个编号应该如何在计算机中存储。那要怎么存储呢,这样就产生了所谓的UTF-8,UTF-16,UTF-32等。下面只具体介绍UTF-8,其他两种编码类似,搞懂一个其他也就能懂。 一种以字节为单位的可变长度字符编码,UTF-8使用1-4字节为每个unicode字符编码,理论上可以最多到6个字节长。这个变化是根据 Unicode 编号的大小有关,编号小的使用的字节就少,编号大的使用的字节就多。 编码规则: 对于0x00-0x7F之间的字符,UTF-8编码与ASCII编码完全相同。UTF-8编码的最大长度是4个字节。从上表可以看出,4字节模板有21个bit(x),即可以容纳21位二进制数字。Unicode的最大码位0x10FFFF也只有21位。 为了更直观的理解,举个栗子:在线验证 “汉”字的Unicode编码是0x6C49。按照UTF-8编码规则,0x6C49在0x0800-0xFFFF之间,使用3字节模板: 1110xxxx 10xxxxxx 10xxxxxx。 将0x6C49写成二进制是:0110 1100 0100 1001, 用这个比特流依次代替模板中的x,得到: 11100110 10110001 10001001,即E6 B1 89。那么这三个字节即是存储在计算机中的“汉”字的编码。 “马”的Unicode编号是:0x9A6C, 按照UTF-8编码规则,在0x0800-0xFFFF之间,其格式为: 1110XXXX 10XXXXXX 10XXXXXX, 0x9A6C对应的二进制是 1001 1010 0110 1100,将二进制填入进入就为: 11101001 10101001 10101100,即E9 A9 AC。 小结: 通常,“字符”被收录进”字符集”,然后按照”字符集”的规模(即要表示多少文字),设计”编码方案”,“编码方案”的 目的是为了使计算机能够表示、识别”字符集”中的”字符”。“字符”、”字符集”是便于人进行阅读的;“编码”是便于计算机进行”阅读”、存储。 在字符编码的发展进程中,不同的国家和地区都有 对自己本地的文字收录进”字符集”,这样就产生了各种”字符集”。汉字相关的字符集就有,GB2312、GBK等。 平常我们所说的“字符集”,如果”字符集”就只有一种”编码”,比如:ASCII、GB2312, GBK等,除了有“字符的集合”这层含义外,同时也包含了“编码”的含义。但是Unicode字符集有多种编码方式,如UTF-8、UTF-16等,但一般我们说unicode编码,通常是值UTF-8。 对于”字符” — “字符集” — “字符编码” 三者之间关系 对于GB2312 对于unicode—utf8 结语: 通过本文对字符编码的理解,我相信,只要搞懂了”字符” — “字符集” — “字符编码” 三者之间关系,不管遇到什么字符集,都能正确的处理不同字符集的字符的转换问题。因为这是最本质的原理,编程语言只是用来 表达字符的工具而已。文章目录
字符(character)
字符集(character set)
字符编码(character encoding)
编码类型
字符的存储
ASCII(American Standard Code for Information Interchange)
GB2312
分区范围
符号类型
第01区
中文标点、数学符号以及一些特殊字符
第02区
各种各样的数学序号
第03区
全角西文字符
第04区
日文平假名
第05区
日文片假名
第06区
希腊字母表
第07区
俄文字母表
第08区
中文拼音字母表
第09区
制表符号
第10-15区
无字符
第16-55区
一级汉字(以拼音字母排序)
第56-87区
二级汉字(以部首笔画排序)
第88-94区
无字符
s = '啊' bytes_gb2312 = bytes(s, encoding='gb2312') print(bytes_gb2312) # 输出结果为 b'xb0xa1'
s = '汉' bytes_gb2312 = bytes(s, encoding='gb2312') print(bytes_gb2312) # 输出结果为 b'xbaxba'
GBK
UNICODE
UTF-8
Unicode编码(十六进制)
UTF-8 字节流(二进制)
000000-00007F
0xxxxxxx
000080-0007FF
110xxxxx 10xxxxxx
000800-00FFFF
1110xxxx 10xxxxxx 10xxxxxx
010000-10FFFF
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
s = '汉' print("{}".format(s)) # 输出结果为 汉 print("{!r}".format(s)) # 输出结果为 '汉' print("{!a}".format(s)) # 输出结果为 'u6c49' bytes1 = bytes(s, encoding='utf-8') print(bytes1) # 输出结果为 b'xe6xb1x89' for b in bytes1: print("{:#b}".format(b)) # for 循环的输出结果为: # 0b11100110 # 0b10110001 # 0b10001001 # 代码执行的结果和前面分析计算的结果完全相同。
“字符”和”字符集” 通常是便于人 表达的 编号 方式
“字符编码” 通常是 让计算机 表达的 编号方式
**字符
区位码(字符集中的编号)
字符 — 区位码(字符集中的编号) — 国标码(字符编码的编号,也是在计算机中的存储表示)
“汉”
0x1A1A
0xBABA
字符
unicode编码(字符集中的编号)
utf8字节流(字符编码的编号,也是在计算机中的存储表示)
“汉”
0x6c49
0xe6b189
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算