赞
踩
常用字符集
位(bit):是计算机 内部数据 储存的最小单位,11001100是一个八位二进制数。
字节(byte):是计算机中 数据处理 的基本单位,习惯上用大写 B 来表示,1B(byte,字节)= 8bit(位)
字符:是指计算机中使用的字母、数字、字和符号
ASCIIS码: 1个英文字母(不分大小写)= 1个字节的空间
1个中文汉字 = 2个字节的空间
1个ASCII码 = 一个字节
UTF-8编码:1个英文字符 = 1个字节
英文标点 = 1个字节
1个中文(含繁体) = 3个字节
中文标点 = 3个字节
Unicode编码:1个英文字符 = 2个字节
英文标点 = 2个字节
1个中文(含繁体) = 2个字节
中文标点 = 2个字节
数据存储是以“字节”(Byte)为单位,数据传输大多是以“位”(bit,又名“比特”)为单位,一个位就代表一个0或1(即二进制),每8个位(bit,简写为b)组成一个字节(Byte,简写为B),是最小一级的信息单位。
B与iB
1KiB(Kibibyte)=1024byte
1KB(Kilobyte)=1000byte
1MiB(Mebibyte)=1048576byte
1MB(Megabyte)=1000000byte
硬盘生产商是以GB(十进制),即10的3次方=1000,如1MB=1000KB)计算的,而电脑(操作系统)是以GiB(2进制,即2的10次方, 如1MiB=1024KiB)计算的,但是国内用户一般理解为1MiB=1M=1024 KB, 所以为了便于中文化的理解,翻译MiB为MB也是可以的。
同样根据硬盘)厂商与用户对于1MB大小的不同理解,所以好多160G的硬盘实际容量按计算机实际的1MiB=1024KB算都不到160G,这也可以解释为什么新买的硬盘“缺斤短两”并没有它所标示的那么大。
国际单位制(SI):
1KB=1024B;1MB=1024KB=1024×1024B。
1B(byte,字节)= 8 bit(见下文);
1KB(Kilobyte,千字节])=1024B= 2^10 B;
1MB(Megabyte,兆字节,百万字节,简称“兆”)=1024KB= 2^20 B;
1GB(Gigabyte,吉字节,十亿字节,又称“千兆”)=1024MB= 2^30 B;
1TB(Terabyte,万亿字节,太字节)=1024GB= 2^40 B;
1PB(Petabyte,千万亿字节,拍字节)=1024TB= 2^50 B;
1EB(Exabyte,百亿亿字节,艾字节)=1024PB= 2^60 B;
1ZB(Zettabyte,十万亿亿字节,泽字节) =102424EB= 2^70 B;
1YB(Yottabyte,一亿亿亿字节,尧字节)= 1024ZB= 2^80 B;
1BB(Brontobyte,一千亿亿亿字节)= 1024YB= 2^90 B;
1NB(NonaByte,一百万亿亿亿字节) = 1024BB = 2^100 B;
1DB(DoggaByte,十亿亿亿亿字节) = 1024 NB = 2^110 B;
数据存储是以10进制表示,数据传输是以2进制表示的,所以1KB不等于1000B。
ASCII
ASCII是7比特的字符集,涵盖了英语中的绝大多数字符。编码从0到127.
ASCII码实现的是大小写英文字母,阿拉伯数字,及常用的标点符、运算符、控制字符(换行、删除等)和通信字符(文头、确认等)与计算机编码之间的对应。ASCII编码采用单字节(8 Bit)存储,实际数据存储空间是7 Bit,最高位的1 Bit是奇偶校验位。
ASCII编码对于英语国家足够用了,但是却无法表达非英语国家字符到计算机编码之间的映射,如中文汉字、法语字母等。所以,出现了很多非ASCII编码(但大多数都是兼容ASCII码的)。
ISOLatin-1(the ISO-8859-1 standard)
ISO Latin-1是8比特的字符集,定义了256个字符。前128个字符(00000000-01111111)与ASCII完全一致。
Latin1是ISO-8859-1的别名,有些环境下写作Latin-1。Latin1编码是单字节编码,向下兼容ASCII,其编码范围是0x00-0xFF,0x00-0x7F之间完全和ASCII一致,0x80-0x9F之间是控制字符,0xA0-0xFF之间是文字符号。
ASCII编码是一个7位的容器,ISO-8859-1编码是一个8位的容器。
因为Latin1编码范围使用了单字节内的所有空间,在支持Latin1编码的系统中传输和存储其他任何编码的字节流都不会被抛弃。换言之,把其他任何编码的字节流当作Latin1编码看待都没有问题。这是个很重要的特性,MySQL数据库默认编码是Latin1就是利用了这个特性。
Unicode
世界上存在着多种编码方式,同一个二进制数字可以被解释成不同的符号。因此,要想打开一个文本文件,就必须知道它的编码方式,否则用错误的编码方式解读,就会出现乱码。为什么电子邮件常常出现乱码?就是因为发信人和收信人使用的编码方式不一样。
可以想象,如果有一种编码,将世界上所有的符号都纳入其中。每一个符号都给予一个独一无二的编码,那么乱码问题就会消失。这就是Unicode。
Unicode当然是一个很大的集合,现在的规模可以容纳100多万个符号。每个符号的编码都不一样需要注意的是,Unicode只是一个符号集,它只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储。
如果所有字符都按照最大存储空间存储,那必然会浪费很大的空间,比如所有字符都按照3字节存储,但是英文字母只需要一个字节存储就够了,就等于说一个Unicode编码的英文文档是ASCII编码文档存储空间的三倍。
所以,便有了变长编码—-UTF-8。
Unicode只是定义了字符的编码值,并未指定值以何种形式存储。比如汉字“田”的Unicode编码是7530,转换为二进制是01110101,00110000。比方现在定义一种unicode的实现方式UTF-FAKE,规则是
a. 使用24个字节
b. 每个字节的高7位都是1
c. 每个字节的最末一位存储unicode编码值
那么01110101,00110000的存储形式是
11111110, 11111110, 11111110, 11111110, 11111110, 11111110, 11111110, 11111110,
11111110, 11111111, 11111111, 11111111, 11111110, 11111111, 11111110, 11111111,
11111110, 11111110, 11111111, 11111111, 11111110, 11111110, 11111110, 11111110
其中末位为蓝色0的字节为补足字节。
实际使用的编码方式UTF-8使用三个字节存储“田” 01110101,00110000,如下
11100111, 10010100, 10110000
Unicode的第一个版本于1991年发布,该版本允许的的最大编码空间是两个字节。96年发布的Unicode 2.0版本引入了surrogate pair,将Unicode的编码数目扩充到了百万级,由于可见的将来该数目不大可能用光,因此Unicode委员会对外宣称该上限永不会更改。Surrogate pair在UTF-16和UTF-32中得到了实现。Unicode的前256个字符及编码值与Latin-1完全一致。比如大写字母A在Latin-1和Unicode中的编码值都是0x41(十进制的65)。
Unicode的编码值范围是 000000hex 到10FFFFhex,可划分为17个plane,每个plane包含65536(= 216)个字符。Plane的代码从0到16(十进制),对应于 000000hex,010000hex,020000hex,… … ,0F0000hex,10FFFFhex的蓝色部分。
Unicode的表示方式一般是”U+”后缀上4到6个十六进制字符,如”田“的Unicode表示方式是U+7530。
UTF-8
UTF-8就是在互联网上使用最广的一种Unicode的实现方式。其他实现方式还包括UTF-16和UTF-32,不过在互联网上基本不用。
UTF-8最大的一个特点,就是它是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。如ASCII编码的内容UTf-8中就是用一个字符存储的。
UTF-8采用可变长度的编码,长度从1到4个字节不等。某些应用识别非标准的"utf8" 或"UTF 8"别名。只有ASCII字符在UTF-8中使用一个字节编码,且值与ASCII完全相同,其余字符在UTF-8中使用2到4个字节。因此UTF-8中的单字节且只有单字节编码字符的最高的1个比特是0。
UTF-8对Unicode字符的编码规则如下
说明如下:
只有ASCII使用单字节编码
Unicode编码值大于127的字符使用多个字节编码。多字节序列的第一个字节称为leading byte,后续的字节称为continuation bytes。Leading byte的高位是110,1110或11110,其中的“1”的个数标明了序列中的字节总数。如2个字节序列的leading byte为110xxxxx,其中的11标明了这是一个双字节的序列,亦即该序列有1个continuation byte。Continuation bytes的每个字节的高两位均是10。
单字节序列、leading bytes和continuationbytes的高位分别是0,110/1110/11110和10,因此不会混淆。
还是以汉字”田“为例,展示Unicode字符如何按照UTF-8存储。”田“的Unicode值是U+7530,比对上表发现介于U+0800 - U+FFFF之间,因此需要3个字节来存储。7530转为二进制是1110101,00110000,一共15位。但由于UTF-8的3字节编码存储16个比特,因此将1110101,00110000的高一位补零变成16比特01110101,00110000。然后将这16比特依次填入三字节序列1110xxxx 10xxxxxx 10xxxxxx的x中,得到结果
11100111 10010100 10110000,写成16进制就是E7 94 B0
注意:虽然Unicode中的前256个字符及编码值与Latin-1完全一致,但UTF-8只对前128个即ASCII字符采用单字节编码,其余128个Latin-1字符是采用2个字节编码。因此ASCII编码的文件可以直接以UTF-8方式读取,而Latin-1的文件若包含值为128-255的字符则不可以。
UTF-8是一种变长字节编码方式。对于某一个字符的UTF-8编码,如果只有一个字节则其最高二进制位为0;如果是多字节,其第一个字节从最高位开始,连续的二进制位值为1的个数决定了其编码的位数,其余各字节均以10开头。UTF-8最多可用到6个字节。
如表:
1字节 0xxxxxxx
2字节 110xxxxx 10xxxxxx
3字节 1110xxxx 10xxxxxx 10xxxxxx
4字节 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
5字节 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
6字节 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx Unicode
UNICODE UTF8转换规则
符号范围 | 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
下面,还是以汉字“严”为例,演示如何实现UTF-8编码。
下面,还是以汉字“严”为例,演示如何实现UTF-8编码。
已知“严”的unicode是4E25(100111000100101),根据上表,可以发现4E25处在第三行的范围内(0000 0800-0000 FFFF),因此“严”的UTF-8编码需要三个字节,即格式是“1110xxxx 10xxxxxx 10xxxxxx”。然后,从“严”的最后一个二进制位开始,依次从后向前填入格式中的x,多出的位补0。这样就得到了,“严”的UTF-8编码是“11100100 10111000 10100101”,转换成十六进制就是E4B8A5。
UTF-16
UTF-16也是采用可变长度编码,可以是一个或者两个16比特。某些应用中允许使用非标准的UTF_16或者UTF16作为别名。Unicode中的第一个plane的65536(= 216)codepoints采用16比特编码,其余的16个plane均采用2个16比特编码。采用2个16比特编码的前后两个16bit分别称为lead surrogate pair和trail surrogate pair,之所以称为surrogate是因为单独一个16bit不代表任何字符,只有组合起来才有意义。
既然UTF-16也是可变长度编码,如何区分某个16bit是单独表示一个字符还是与后续的16bit组合起来表示一个字符呢?Unicode将D800–DBFF和DC00–DFFF这两个范围作为保留区间,没有将之分配给任何Unicode字符,若某16比特落在D800–DBFF范围内,便可将之视为采用2个16bit编码字符的第一个16bit,而落在DC00–DFFF的16bit可视为采用2个16bit编码字符的第二个16bit。这就使得Unicode第一个plane实际可分配使用的code points只有65536 – (DFFF - D800 + 1) = 65536 – 8*256 = 63488。
采用一个16bit编码的Unicode字符在UTF-16中的编码值与其在Unicode中是相等的,比如英文大写字母A的Unicode值是U+0041,其UTF-16编码是0041 hex 。Unicode第二到第十七个plane采用两个16bit即surrogate pairs的字符从其Unicode code point到UTF-16的转换规则是
范围为0x10000 … 0x10FFFF的codepoint减去0x010000,减过后的结果范围是0x00000到0xFFFFF,使得该结果可以使用5位16进制亦即20位2进制数表示
结果中高10位(范围是0x0到0x3FF)加上0xD800(结果范围是0xD800到0xDBFF)作为双16bit的第一个16bit即leadsurrogate
结果中低10位(范围是0x0到0x3FF)加上0xDC00(结果范围是0xDC00到0xDFFF)作为双16bit的第二个16bit即trailsurrogate
这样UTF-16与UTF-8都是self-synchronizing的,即某个16bit是否是一个字符的开始无需检查其前一个或者后一个16bit。与UTF-8的不同之处是,UTF-16不支持从某个随机的字节开始读取。
举例:UTF-16 序列 0041, D801DC01 (字符"A"),若第一个字节丢失即从第二个字节读取,那么UTF-16认为序列是41D8,01DC,01;而UTF-8不存在这个问题。
GKB
GBK 是又一个汉字编码标准,全称《汉字内码扩展规范》(GBK),英文名称 Chinese Internal Code Specification ,中华人民共和国全国信息技术标准化技术委员会 1995 年 12 月 1 日制订,国家技术监督局标准化司、电子工业部科技与质量监督司 1995 年 12 月 15 日联合以技监标函 [1995] 229 号文件的形式,将它确定为技术规范指导性文件,发布和实施。这一版的 GBK 规范为 1.0 版。GB 即“国标”,K 是“扩展”的汉语拼音第一个字母。
GBK 向下与 GB 2312 编码兼容,向上支持 ISO 10646.1 国际标准,是前者向后者过渡过程中的一个承上启下的标准。
ISO 10646 是国际标准化组织 ISO 公布的一个编码标准,即 Universal Multilpe-Octet Coded Character Set(简称 UCS),大陆译为《通用多八位编码字符集》,台湾译为《广用多八位元编码字元集》,它与 Unicode 组织的 Unicode 编码完全兼容。ISO 10646.1 是该标准的第一部分《体系结构与基本多文种平面》。我国 1993 年以 GB 13000.1 国家标准的形式予以认可(即 GB 13000.1 等同于 ISO 10646.1)。
ISO 10646 是一个包括世界上各种语言的书面形式以及附加符号的编码体系。其中的汉字部分称为“CJK 统一汉字”(C 指中国,J 指日本,K 指朝鲜)。而其中的中国部分,包括了源自中国大陆的 GB 2312、GB 12345、《现代汉语通用字表》等法定标准的汉字和符号,以及源自台湾的 CNS 11643 标准中第 1、2 字面(基本等同于 BIG-5 编码)、第 14 字面的汉字和符号。
一、字汇
GBK 规范收录了 ISO 10646.1 中的全部 CJK 汉字和符号,并有所补充。具体包括:
GB 2312 中的全部汉字、非汉字符号。
GB 13000.1 中的其他 CJK 汉字。以上合计 20902 个 GB 化汉字。
《简化字总表》中未收入 GB 13000.1 的 52 个汉字。
《康熙字典》及《辞海》中未收入 GB 13000.1 的 28 个部首及重要构件。
13 个汉字结构符。
BIG-5 中未被 GB 2312 收入、但存在于 GB 13000.1 中的 139 个图形符号。
GB 12345 增补的 6 个拼音符号。
汉字“○”。
GB 12345 增补的 19 个竖排标点符号(GB 12345 较 GB 2312 增补竖排标点符号 29 个,其中 10 个未被 GB 13000.1 收入,故 GBK 亦不收)。
从 GB 13000.1 的 CJK 兼容区挑选出的 21 个汉字。
GB 13000.1 收入的 31 个 IBM OS/2 专用符号。
二、码位分配及顺序
GBK 亦采用双字节表示,总体编码范围为 8140-FEFE,首字节在 81-FE 之间,尾字节在 40-FE 之间,剔除 xx7F 一条线。总计 23940 个码位,共收入 21886 个汉字和图形符号,其中汉字(包括部首和构件)21003 个,图形符号 883 个。
全部编码分为三大部分:
汉字区。包括:
a. GB 2312 汉字区。即 GBK/2: B0A1-F7FE。收录 GB 2312 汉字 6763 个,按原顺序排列。
b. GB 13000.1 扩充汉字区。包括:
(1) GBK/3: 8140-A0FE。收录 GB 13000.1 中的 CJK 汉字 6080 个。
(2) GBK/4: AA40-FEA0。收录 CJK 汉字和增补的汉字 8160 个。CJK 汉字在前,按 UCS 代码大小排列;增补的汉字(包括部首和构件)在后,按《康熙字典》的页码/字位排列。
图形符号区。包括:
a. GB 2312 非汉字符号区。即 GBK/1: A1A1-A9FE。其中除 GB 2312 的符号外,还有 10 个小写罗马数字和 GB 12345 增补的符号。计符号 717 个。
b. GB 13000.1 扩充非汉字区。即 GBK/5: A840-A9A0。BIG-5 非汉字符号、结构符和“○”排列在此区。计符号 166 个。
用户自定义区:分为(1)(2)(3)三个小区。
(1) AAA1-AFFE,码位 564 个。
(2) F8A1-FEFE,码位 658 个。
(3) A140-A7A0,码位 672 个。
第(3)区尽管对用户开放,但限制使用,因为不排除未来在此区域增补新字符的可能性。
三、字形
GBK 对字形作了如下的规定:
原则上与 GB 13000.1 G列(即源自中国大陆法定标准的汉字)下的字形/笔形保持一致。
在 CJK 汉字认同规则的总框架内,对所有的 GBK 编码汉字实施“无重码正形”(“GB 化”);即在不造成重码的前提下,尽量采用中国新字形。
对于超出 CJK 汉字认同规则的、或认同规则尚未明确规定的汉字,在 GBK 码位上暂安放旧字形。这样,在许多情况下 GBK 收入了同一汉字的新旧两种字形。
非汉字符号的字形,凡 GB 2312 已经包括的,与 GB 2312 保持一致;超出 GB 2312 的部分,与 GB 13000.1 保持一致。
带声调的拼音字母取半角形式。
GBK编码是在GB2312-80(也称作GB2312,GB码)标准基础上的内码扩展规范,使用了双字节编码方案。
GBK是国家标准GB2312基础上扩容后兼容GB2312的标准。GBK的文字编码是用双字节来表示的,即不论中、英文字符均使用双字节来表示,为了区分中文,将其最高位都设定成1。GBK包含全部中文字符,是国家编码,通用性比UTF8差,不过UTF8占用的数据库比GBK大
GBK、GB2312等与UTF8之间都必须通过Unicode编码才能相互转换:
GBK、GB2312<= = =>Unicode<= = =>UTF8
补充:
GB2312 最早一版的中文编码,每个字占据2bytes。由于要和ASCII兼容,那这2bytes最高位不可以为0了(否则和ASCII会有冲突)。在GB2312中收录了6763个汉字以及682个特殊符号,已经囊括了生活中最常用的所有汉字。
GBK 由于GB2312只有6763个汉字,我汉语博大精深,只有6763个字怎么够?于是GBK中在保证不和GB2312、ASCII冲突(即兼容GB2312和ASCII)的前提下,也用每个字占据2bytes的方式又编码了许多汉字。经过GBK编码后,可以表示的汉字达到了20902个,另有984个汉语标点符号、部首等。值得注意的是这20902个汉字还包含了繁体字。
GB18030 然而,GBK的两万多字也已经无法满足我们的需求了,还有更多可能你自己从来没见过的汉字需要编码。这时候显然只用2bytes表示一个字已经不够用了(2bytes最多只有65536种组合,然而为了和ASCII兼容,最高位不能为0就已经直接淘汰了一半的组合,只剩下3万多种组合无法满足全部汉字求)。因此GB18030多出来的汉字使用4bytes编码。当然,为了兼容GBK,这个四字节的前两位显然不能与GBK冲突(实操中发现后两位也并没有和GBK冲突)。我国在2000年和2005年分别颁布的两次GB18030编码,其中2005年的是在2000年基础上进一步补充。至此,GB18030编码的中文文件已经有七万多个汉字了,甚至包含了少数民族文字。
这图中展示了前文所述的几种编码在编码完成后,前2个byte的值的范围(用16进制表示)。每个byte可以表示00到FF(即0至255)。从图中我们可以一目了然地看到为什么GB18030可以兼容GBK,GB2312和ASCII了。他们几种编码之间前两位没有重合部分。需要注意的是ASCII只有1byte,所以是没有第二位的。另外GB18030在上图中占的面积虽然很小,但是它是4bytes编码,这图只展示了前两位。如果后两位也算上,GB18030的字数要远多于GBK。另外需要注意的是,由于GBK兼容GB2312,因此属于GB2312的蓝色区域其实也可以算作是GBK的区域。同理GBK的区域理论上也属于GB18030的区域。上表中只是展示了多出来的部分。
实际生活中,我们用到的99%以上的汉字,其实都在GB2312那一块区域内。至于GB2312每个编码对应的到底是哪个汉字本文不再赘述,可以参考链接(链接地址)查询。GBK编码所对应的汉字可以参考链接(链接地址)查询。至于GB18030编码,由于字数实在太多太难写,已经很难在网上找到在线的编码全表了。不过经过一番搜寻,还是找到了我国发布GB18030编码时的相关文档(GB18030-2005文档、 GB18030-2000文档)。
在实际使用中,GBK编码已经可以满足大部分场景了,GB18030编码中所有汉字都是我们这辈子都不一定能见到的文字,这也是平时为什么经常会使用GBK的原因吧。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。