字符集的那些事
一:字符集发展史,常见字符集及其编码规则
- ASCII —— American Standard Code for Information Interchange: 美国信息交换标准代码 ASCII第一次以规范标准的形式发表是在1967年,最后一次更新则是在1986年,到目前为止共定义了128个字符。这是最早出现的最原始的字符集。 其内容可参见文末。
ANSI 字符集:所谓ANSI字符集并不是指某一种特殊的字符集。它实际上是指不同国家根据自己需求所定义的字符集的总称。 就比如中国的GB2312(GBK、GB18030)和BIG5,日本的Shift-JIS,以及其他国家定义的ASCII扩展字符集。
- GB2312
《信息交换用汉字编码字符集》是由中国国家标准总局1980年发布,1981年5月1日开始实施的一套国家标准,标准号是GB 2312—1980。
GB2312标准共收录6763个汉字,其中一级汉字3755个,二级汉字3008个;同时,GB2312收录了包括拉丁字母、希腊字母、日文平假名及片假名字母、俄语西里尔字母在内的682个全角字符。
GB2312的出现,基本满足了汉字的计算机处理需要,它所收录的汉字已经覆盖中国大陆99.75%的使用频率。 但是对于人名、古汉语等方面出现的罕用字,GB2312不能处理,这导致了后来GBK及GB18030汉字字符集的出现。
分区表示:
GB2312对所收汉字进行了“分区”处理,每区含有94个汉字/符号。这种表示方式也称为区位码。
01-09区为特殊符号。
16-55区为一级汉字,按拼音排序。
56-87区为二级汉字,按部首/笔画排序。
10-15区及88-94区则未有编码。
举例来说,“啊”字是GB2312之中的第一个汉字,它的区位码就是1601。
双字节编码:
GB2312规定对收录的每个字符采用两个字节表示,第一个字节为“高字节”,对应94个区;第二个字节为“低字节”,对应94个位。所以它的区位码范围是:0101-9494(十进制表示)。
区号和位号分别加上0xA0就是GB2312编码。
例如:“啊”的区位码是0x1001, 区号和位号分别加上0xA0,得到的0xB0A1就是其GB2312编码。
GB2312编码范围:A1A1-FEFE
其中汉字的编码范围为B0A1-F7FE,第一字节0xB0-0xF7(对应区号:16-87),第二个字节0xA1-0xFE(对应位号:01-94)。
GB2312具体字符的编码值及编码规则可查看此工具网站。
- Unicode
在全世界出现了很多不同的ANSI字符集之后,很多国家都在为自己的文字编码,并且互不想通,这就造成不同的语言字符编码值相同却代表不同的符号(例如:韩文编码EUC-KR中“한국어”的编码值正好是汉字编码GBK中的“茄惫绢”)。因此,同一份文档,拷贝至不同语言环境(Locale)的机器,就可能成了乱码。所以,全球字符大一统的需求应运而生。
首先需要明确一点的是Unicode并不是一种字符编码方式,它仅仅是一个字符集。但是这个字符集特别的大,大到足以容纳全世界所有的字符。从而可以让全世界都统一使用同一套字符集,并且可以让全世界都使用相同的编码格式(UTF-8/16/32),从而解决乱码的问题。
推进全球字符集大一统的两大组织:
(1) 国际标准化组织(ISO),他们于1984年创建ISO/IEC JTC1/SC2/WG2工作组,试图制定一份“通用字符集”(Universal Character Set,简称UCS),并最终制定了ISO 10646标准。
(2) 统一码联盟,他们由Xerox、Apple等软件制造商于1988年组成,并且开发了Unicode标准(The Unicode Standard,这个前缀Uni 代表了 Universal,Unique, and Uniform)。
1991年前后,两个项目的参与者都认识到,世界不需要两个不兼容的字符集。于是,它们开始合并双方的工作成果,并为创立一个单一编码表而协同工作。从Unicode 2.0开始,Unicode采用了与ISO 10646-1相同的字库和字码;ISO也承诺,ISO 10646将不会给超出U+10FFFF的字符编号,以使得两者保持一致。两个项目仍都独立存在,并独立地公布各自的标准。不过由于Unicode这一名字比较好记,因而它使用更为广泛。
与Unicode相关的一系列重要概念
Code Point、Plane、BMP:
在实际编码(考虑存储)之前先给每个穷举到的字符编号,即是Code Point(码位),把它当做是数学概念,和用几个字节存储无关,只要发布Unicode 的标准化组织(ISO 和 统一码联盟)愿意,将新出现的字符继续向后编号就可以了,既然是数学序号,那就没有什么不够用的问题。
在编号的过程中,标准化组织还将用到的数字编号(码位)进行了分区操作。从而引出了Plane(平面)的概念。即将256×256=65536个码位作为一个平面(一个二维平面,长宽均为256个编号)。
此外,在对全球字符编号时有一些原则,就是将越常用的字符越靠前。所以,前65536个字符所构成的第一个Plane(平面),这个平面就叫做基本多文种平面(BMP - Basic Multilingual Plane)。而大于BMP最大值的码位所构成的平面,就被称作辅助平面。并且ISO和统一码联盟为了兼容问题,协商确定最多使用16个辅助平面。
以下是辅助平面中16个平面的名称和编码范围:
平面 | 编码范围 | 中文名称 | 英文名称 |
---|---|---|---|
0号平面 | U+0000 - U+FFFF | 基本多文种平面 | Basic Multilingual Plane,简称BMP |
1号平面 | U+10000 - U+1FFFF | 多文种补充平面 | Supplementary Multilingual Plane,简称SMP |
2号平面 | U+20000 - U+2FFFF | 表意文字补充平面 | Supplementary Ideographic Plane,简称SIP |
3号平面 | U+30000 - U+3FFFF | 表意文字第三平面 | Tertiary Ideographic Plane,简称TIP |
4~13号平面 | U+40000 - U+DFFFF | (尚未使用) | |
14号平面 | U+E0000 - U+EFFFF | 特别用途补充平面 | Supplementary Special-purpose Plane,简称SSP |
15号平面 | U+F0000 - U+FFFFF | 保留作为私人使用区(A区) | Private Use Area-A,简称PUA-A |
16号平面 | U+100000 - U+10FFFF | 保留作为私人使用区(B区) | Private Use Area-B,简称PUA-B |
UTF-16编码规则(关于代理对的概念后续再补上):
标签:编码,UTF,字符集,GBK,Unicode,字符串 From: https://www.cnblogs.com/yyybill/p/17132440.html
前面提到过:Unicode码位分为17个平面(1个BMP+16个辅助平面)。
在BMP内的字符,UTF-16直接使用Unicode码位作为其编码值。 如:“汉”在Unicode中的码位为6C49,所以UTF-16编码也为496C(该值为大端表示,小端为6C49)。
在辅助平面内的字符,按照以下规则编码: 用它们在Unicode中码位减去0x10000获得一个数字,使用该数字二进制的前10位(bits)加上0xD800,就得到UTF-16四字节编码中的前两个字节;该数字的后10位(bits)加上0xDC00,就得到UTF-16四字节编码中的后两个字节。
如:“