字符集与字符编码

本文深入探讨字符集和字符编码的区别,包括ASCII、GB2312、GBK、GB18030、Big5字符集及编码,以及Unicode字符集和UTF编码的原理与特点。通过对比分析,解释了BOM(字节序标记)在不同编码中的作用,同时介绍了ANSI编码的含义。最后,阐述了解析文本文件时如何正确识别编码类型以避免乱码问题。
摘要由CSDN通过智能技术生成

目录

1.  概述

1.1 基本概念

1.2 映射关系

2.  ASCII字符集及编码

3.  GBXXXX字符集及编码

3.1 GB2312

3.2 GBK

3.3 GB 18030

3.4 代码页

4.  Big5字符集&编码

5.  Unicode字符集

6.  UTF编码

6.1. UTF-32编码

6.2. UTF-16编码

6.3. UTF-8编码

6.4.  Unicode编码范围

7.  BOM(Byte order mark)

7.1 大端及小端

7.2 UTF-8

7.3 UTF-16

7.4 UTF-32

8.  ANSI

9.  读取文本文件

10. 参考资料 


作为一个程序员,很有可能被字符集和字符编码给坑过(如果没有,那可能是业务不同,也可能是时候未到)。最简单的问题,字符集和字符编码有啥关系?我们常常听到的GBK、GB2312、Code page 936到底是什么,它们的关系是什么?再譬如,为什么写爬虫代码时,获取到的是乱码(或者在其他环境下打开Windows下的文本文件会出现乱码)?再譬如UTF-8、UTF-16、UTF-32的关系是什么,它们和Unicode的关系又是什么?

我之前也糊里糊涂,最近这几天看了很多文档(建议直接看Wiki),终于把这个问题给理清了。文章有点长,还请耐心阅读。

1.  概述

1.1 基本概念

字符集(Character set),顾名思义是字符的集合。字符是各种文字和符号的总称,包括文字、标点符号、图形符号、数字、控制符号等。常用的字符集有:ASCII字符集、GB2312字符集、GBK字符集、GB 18030字符集、Big5字符集、Unicode字符集等。 

字符编码(Character Encoding),是字符的编码方式,是将字符集中的字符码映射为字节流的一种具体实现方案。例如ASCII字符编码规定使用单字节中低位的7个比特去编码所有的字符。例如字母’A’的编号是65(ASCII码),用单字节表示就是0x41,因此写入存储设备的时候就是b’01000001’。常用的字符编码方式有ASCII编码、UTF-8编码、GBK编码、Big5编码等。

字符码(Code point):也称编码点,在每个字符集中,每个字符有个编号,称之为字符集编号,该编号就是字符码。Code point(code point or code position is any of the numerical values that make up the code space,该字符在子库表中的位置)。譬如,ASCII字符集中字母’A’的字符码就是65。 

字符集和字符编码是完全不同的概念。字符编码依赖于字符集,没有字符集,字符编码就无意义,也就是说字符集是字符编码的基础。一个字符集可以有多个编码实现,所以有众多的字符编码方式。对于ASCII、GB2312、Big5、GBK,其既是字符集,本身又是字符编码方式,所以会让人很混乱,这个不冲突,后续会详细讲。

1.2 映射关系

1. 字符集与字符编码一对一映射

有很多的字符编码方案,一个字符集只有唯一的编码实现,两者是一一对应的。比如 GB2312,这种情况,无论你怎么去称呼它们,比如“GB2312编码”,“GB2312字符集”,说来说去其实都是一个东西,可能它本身就没有特意去做什么区分,所以无论怎么说都不会错。

为什么一对一是一种普遍的情况呢?

我们以 GB2312 为例,GB(国家标准),标准出来本来就为了统一,你一个标准弄出 N 个编码实现来,你让人家用哪个呢?

2. 字符集与编码一对多映射

事情到了 Unicode 这里,变得不一样了,唯一的 Unicode 字符集对应了三种编码:UTF-8,UTF-16,UTF-32。如果还是这么笼统地去称呼,就很容易搞混了。对于Unicode,还有UCS-2、UCS-4等编码方案,更让人傻傻分不清。

2.  ASCII字符集及编码

ASCII(美国信息交换标准代码)是基于拉丁字母的一套电脑编码系统。它主要用于显示现代英语,而其扩展版本EASCII则可以勉强显示其他西欧语言。它是现今最通用的单字节编码系统,并等同于国际标准ISO/IEC 646。

ASCII字符集:主要包括控制字符(回车键、退格、换行键等);可显示字符(英文大小写字符、阿拉伯数字和西文符号)。

ASCII编码:将ASCII字符集转换为计算机可以接受的数字系统的数的规则。使用7位(bits)表示一个字符,共128字符,ASCII字符集映射到数字编码规则如下图所示:

编码特点:

1. 遵循ASCII字符集,共含有128个字符

2. 使用1个字节存储

ASCII字符集只能显示127个字符,因为只使用了1个字节中的低7Bit,为了扩展,也将最高位也用上,就是EASCII,表示ASCII的扩展: ASCII扩展字符集使用8位(bits)表示一个字符,共256字符,扩展部分如下图所示:

3.  GBXXXX字符集及编码

3.1 GB2312

ASCII字符集中没有汉字,所以中国制定了汉字的字符集GB2312。在国标GB2312-80(1980年颁布)中规定,所有的国标汉字及符号分配在一个94行、94列的方阵中,方阵的每一行称为一个“区”,编号为01区到94区,每一列称为一个“位”,编号为01 位到94位,方阵中的每一个汉字和符号所在的区号和位号组合在一起形成的长度为四的阿拉伯数字就是它们的“区位码”。

国标码(国家标准汉字交换码,也称为交换码):1980年中国制定的用于不同的具有汉字处理功能的计算机系统间交换汉字信息时使用的编码(GB2312),这种编码又称为国标码。

在国标码的字符集中共收录了一级汉字3755个,二级汉字3008 个,图形符号682个,三项字符总计7445个。  

一级汉字为常用字,按拼音顺序排列,二级汉字为次常用字,按部首排列。国标码的范围是2121H---7E7EH。

机内码(内码):汉字在计算机汉字系统内部的表示方法,是计算机汉字系统的基础代码。

区位码其实是和ASCII码是有重复的。ASCII码的前32个为控制字符,因此将区位码的每一行、每一列偏移32(0x32)就得到了国标码。但是国标码又和ASCII的普通字符冲突,为了兼容ASCII码,于是将国标码的区及位的字节的高位置为1,也就是加上0x80,得到机内码(内码)。

从上述看,GB2312是不兼容E-ASCII的。

国标码、机内码、区位码的转换关系如下:

1. 国标码(交换码)与区位码

国标码高位字节=(区号)H+20H

国标码低位字节=(位号)H+20H

2. 机内码与区位码

机内码高位字节=(区号)H+A0H (128 + 32)

机内码低位字节=(位号)H+A0H(128 + 32)

3. 机内码和国标码

机内码高位字节=国标码高位字节 + 80H

机内码低位字节=国标码高位字节 + 80H(最高位由0变为1)

 GB2312字符集的编码规则为:一个小于127的字符的意义与原来相同,但两个大于127的字符连在一起时,就表示一个汉字,前面的一个字节(他称之为高字节)从0xA1用到 0xF7,后面一个字节(低字节)从0xA1到0xFE,这样我们就可以组合出大约7000多个简体汉字了。在这些编码里,还把数学符号、罗马希腊的字母、日文的假名们都编进去了。将在ASCII里本来就有的数字、标点、字母都重新编为两个字节长的编码,这就是常说的"全角"字符,而原来在127号以下的那些就叫"半角"字符了

编码特点:

1. 遵循GB2312字符集,支持常见的中文

2. 使用1个字节存储英文和数字等字符,使用2个字节存储中文字符

3. GB2312兼容ASCII

GB2312编码通行于中国大陆;新加坡等地也采用此编码。GB2312基本满足了汉字的计算机处理需要,它所收录的汉字已经覆盖中国大陆99.75%的使用频率。对于人名、古汉语等方面出现的罕用字,GB2312不能处理,这导致了后来GBK及GB 18030汉字字符集的出现。列举部分汉字,具体可查看GB2312简体中文编码表:

3.2 GBK

由于GB 2312字符集只收录6763个汉字,有不少汉字,如部分在GB 2312推出以后才简化的汉字,部分人名用字,繁体字,日语及朝鲜语汉字等,并未有收录在内。于是就出现了让众多程序员头疼的GBK(微软提出,其他平台不一定支持)。 

GBK(国标扩展,GuobiaoKuozhan)是GB2312字符集的一个扩展,收录GB 13000.1-93全部字符制定了GBK编码。GBK是对GB2312的扩展,最早实现于Windows 95简体中文版。虽然GBK收录GB 13000.1-93的全部字符,但编码方式并不相同。GBK自身并非国家标准,只是曾由国家技术监督局标准化司、电子工业部科技与质量监督司公布为"技术规范指导性文件"。原始GB13000一直未被业界采用,后续国家标准GB18030技术上兼容GBK而非GB13000。

GBK 共收入 21886 个汉字和图形符号,包括:

1. GB 2312 中的全部汉字、非汉字符号

2. Big5 中的全部汉字

3. 与 ISO 10646 相应的国家标准 GB 13000 中的其它 CJK 汉字,以上合计 20902 个汉字

4. 其它汉字、部首、符号,共计 984 个

GBK 向下与 GB 2312 完全兼容,向上支持 ISO 10646 国际标准,在前者向后者过渡过程中起到的承上启下的作用。

编码特点:

1. 遵循GBK字符集,支持常见的中文,罕见中文,繁体中文,日文的假名。

2. 使用1个字节存储英文和数字等字符,使用2个字节存储中文字符。

3. GBK兼容ASCII与GB2312

GBK 采用双字节表示,总体编码范围为 8140-FEFE 之间,首字节在 81-FE 之间,尾字节在 40-FE 之间,剔除 XX7F 一条线。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值