Open chenqunfeng opened 8 years ago
我们在计算机屏幕上的文字,不管是中文也好,英文也罢,甚至是其他国家的语言文字,它们在计算机中的存储实际上是二进制的比特流。既然是二进制的比特流,那么从二进制比特流到能正确显示文字,则在这两者之间需要一个转换规则。
字集码是把字符集中的字符编码为指定集合中某一对象,以便文本在计算机中存储和通过通信网络的传递。而对于一个字符集,若要将一个编码进行正确的转码,需要三个关键元素:字库表(character repertoire)、编码字符集(coded character set)、字符编码(character encoding form)。其中字库表决定整个字符集所有字符的范围;编码字符集是用一个编码(code point)来表示一个字符在字库中的位置;字符编码则表示编码字符集和实际存储值之间的转换关系,不过一般都会直接将编码(code point)直接存储。
中文为万国码、国际码、统一码、单一码(统一码联盟制定),是计算机科学领域里的一项业界标准。它对世界上大部分的文字系统进行整理、编码,使得电脑可以用更为简单的方式来呈现和处理文字。 Unicode是国际组织指定的可以容纳世界上所有文字和符号的字符编码方案。目前的Unicode字符分为17组编排,0x0000到0x10FFFF(00,01,02,03...0F,10),每组称为平面,每平面拥有65536个码位,共1114112个。 通用字符集(UCS)是由ISO 10646(或称ISO/IEC 10646)标准所定义的标准字符集。UCS-2用两个字节编码,UCS-4是一个更大的尚未填充完全的31位字符集,加上恒为0的首位,共32位,用四个字节编码(实际上最大码位为0x7FFFFFFF,共有2的31次方为20亿个)。 统一码联盟和ISO分别制定了Unicode和UCS,但事实上两者都在做同样的事情,所以双方进行了整合。直到Unicode2.0时,Unicode的编码和UCS的编码基本一致。 虽然Unicode在编码上和UCS保持一致,但是在实现上有自己的规则,而UCS只定义了编码标准。Unicode的实现方式有UTF-8,UTF-16,UTF-32还有UTF-7等。 其中UTF-16是UCS-2的扩展,UTF-32是UCS-4的子集。
UTF-8(8-bit Unicode Transformation Format)是一种针对Unicode的可变长字符编码。现在标准化为RFC 3629,使用1到4个字节编码Unicode字符。
对与UTF-8中的任意字节B
例子:
00000000 00000000 0xxxxxxx => 0xxxxxxx(ASCII码范围) 00000000 00000xxx yyyyyyyy => 110xxxyy 10yyyyyy(第一个字节由110开始,接着的字节由10开始) 00000xxx yyyyyyyy zzzzzzzz => 11110xxx 10yyyyyy 10yyzzzz 10zzzz00(第一个字节由11110开始,接着的字节由10开始) ......
优点:
缺点:
UTF-16是Unicode字符编码五层次模型的第三层:字符编码表的一种实现方式。即把Unicode字符集的抽象码位映射为16位长的整数序列,用于数据存储或传递,是Unicode的一种变长表示(UTF-16使用16位长的整数表示,而Unicode需要1个或者2个16位长的码元来表示 )。
辅助平面(Supplementary Planes)中的码位,在UTF-16中被编码为一对(两个)16比特长的码元(即32bit,4Bytes),称作代理对,具体方法如下:
如U+10437
UTF-16大尾序表示为(UTF-16BE):0xD801 0xDC37 UTF-16小尾序表示为(UTF-16LE):0x01D8 0x37DC UTF-16大小尾的区分方式: 在UTF-16文件的开首,都会放置一个U+FEFF字符作为Byte Order Mark,其中U+FFFE为UTF-16LE,U+FEFF为UTF-16RE。
UTF-32(或UCS-4)是一种将Unicode字符编码的协定,对每一个Unicode码位使用恰好32位。因为UTF-32对每个字符都使用4字节,虽然固定字节在使用上会比较方便,但是却是其他编码占用大小的二到四倍,是非常没有效率的。 UTF-32是UCS-4的子集。UCS-4用来表示所有Unicode的字码空间,最大码位为0x7FFFFFFF,共有20亿个,但是如此大的字码空间实际上却只利用了很小的字码集,所以更小的码集被提出,也就是UTF-32,使用32位,范围在0x000000到0x10FFFF,共1114112个。
假设"甲"的Unicode编码为594E,"乙"的Unicode编码为4E59,当我们收到UTF-16字节流"594E",那么我们如何确定这个字节流是"甲"还是"乙"呢(UTF-16有小尾序和大尾序两种表示方法)?
Unicode规范中推荐的标记字节顺序的方法就是BOM,Byte Order Mark。 UCS编码中有一个叫做ZERO WIDTH NO-BREAK SPACE的字符,它的编码为FEFF。而FEFF在UCS中是不存在的字符,所以不应该出现在实际的字节流传输中。所以UCS规范建议我们在传输字节流前,先传输字符ZERO WIDTH NO-BREAK SPACE。因此,如果接受方接受到FEFF,则表明该字节流为大尾序;若为FFFE,则表明该字节流为小尾序。因此,ZERO WIDTH NO-BREAK SPACE又被称作BOM。 UTF-8没有像UTF-16大小尾序的表示方法,所以是不需要BOM来表明字节顺序的,但是也可以用BOM来表明编码方式,字符ZERO WIDTH NO-BREAK SPACE的UTF-8编码是EF BB BF,这也是UTF-8有含有BOM和没有BOM的原因。
GBK等
前言
我们在计算机屏幕上的文字,不管是中文也好,英文也罢,甚至是其他国家的语言文字,它们在计算机中的存储实际上是二进制的比特流。既然是二进制的比特流,那么从二进制比特流到能正确显示文字,则在这两者之间需要一个转换规则。
介绍
字集码是把字符集中的字符编码为指定集合中某一对象,以便文本在计算机中存储和通过通信网络的传递。而对于一个字符集,若要将一个编码进行正确的转码,需要三个关键元素:字库表(character repertoire)、编码字符集(coded character set)、字符编码(character encoding form)。其中字库表决定整个字符集所有字符的范围;编码字符集是用一个编码(code point)来表示一个字符在字库中的位置;字符编码则表示编码字符集和实际存储值之间的转换关系,不过一般都会直接将编码(code point)直接存储。
字符集
Unicode
中文为万国码、国际码、统一码、单一码(统一码联盟制定),是计算机科学领域里的一项业界标准。它对世界上大部分的文字系统进行整理、编码,使得电脑可以用更为简单的方式来呈现和处理文字。 Unicode是国际组织指定的可以容纳世界上所有文字和符号的字符编码方案。目前的Unicode字符分为17组编排,0x0000到0x10FFFF(00,01,02,03...0F,10),每组称为平面,每平面拥有65536个码位,共1114112个。 通用字符集(UCS)是由ISO 10646(或称ISO/IEC 10646)标准所定义的标准字符集。UCS-2用两个字节编码,UCS-4是一个更大的尚未填充完全的31位字符集,加上恒为0的首位,共32位,用四个字节编码(实际上最大码位为0x7FFFFFFF,共有2的31次方为20亿个)。 统一码联盟和ISO分别制定了Unicode和UCS,但事实上两者都在做同样的事情,所以双方进行了整合。直到Unicode2.0时,Unicode的编码和UCS的编码基本一致。 虽然Unicode在编码上和UCS保持一致,但是在实现上有自己的规则,而UCS只定义了编码标准。Unicode的实现方式有UTF-8,UTF-16,UTF-32还有UTF-7等。 其中UTF-16是UCS-2的扩展,UTF-32是UCS-4的子集。
编码方案
UTF-8
UTF-8(8-bit Unicode Transformation Format)是一种针对Unicode的可变长字符编码。现在标准化为RFC 3629,使用1到4个字节编码Unicode字符。
编码方式(算法)
对与UTF-8中的任意字节B
例子:
00000000 00000000 0xxxxxxx => 0xxxxxxx(ASCII码范围) 00000000 00000xxx yyyyyyyy => 110xxxyy 10yyyyyy(第一个字节由110开始,接着的字节由10开始) 00000xxx yyyyyyyy zzzzzzzz => 11110xxx 10yyyyyy 10yyzzzz 10zzzz00(第一个字节由11110开始,接着的字节由10开始) ......
优点:
缺点:
UTF-16
UTF-16是Unicode字符编码五层次模型的第三层:字符编码表的一种实现方式。即把Unicode字符集的抽象码位映射为16位长的整数序列,用于数据存储或传递,是Unicode的一种变长表示(UTF-16使用16位长的整数表示,而Unicode需要1个或者2个16位长的码元来表示 )。
编码方式(算法)
辅助平面(Supplementary Planes)中的码位,在UTF-16中被编码为一对(两个)16比特长的码元(即32bit,4Bytes),称作代理对,具体方法如下:
例子:
如U+10437
UTF-16大尾序表示为(UTF-16BE):0xD801 0xDC37 UTF-16小尾序表示为(UTF-16LE):0x01D8 0x37DC UTF-16大小尾的区分方式: 在UTF-16文件的开首,都会放置一个U+FEFF字符作为Byte Order Mark,其中U+FFFE为UTF-16LE,U+FEFF为UTF-16RE。
UTF-32
UTF-32(或UCS-4)是一种将Unicode字符编码的协定,对每一个Unicode码位使用恰好32位。因为UTF-32对每个字符都使用4字节,虽然固定字节在使用上会比较方便,但是却是其他编码占用大小的二到四倍,是非常没有效率的。 UTF-32是UCS-4的子集。UCS-4用来表示所有Unicode的字码空间,最大码位为0x7FFFFFFF,共有20亿个,但是如此大的字码空间实际上却只利用了很小的字码集,所以更小的码集被提出,也就是UTF-32,使用32位,范围在0x000000到0x10FFFF,共1114112个。
小扩展:UTF中的BOM
例子:
假设"甲"的Unicode编码为594E,"乙"的Unicode编码为4E59,当我们收到UTF-16字节流"594E",那么我们如何确定这个字节流是"甲"还是"乙"呢(UTF-16有小尾序和大尾序两种表示方法)?
Unicode规范中推荐的标记字节顺序的方法就是BOM,Byte Order Mark。 UCS编码中有一个叫做ZERO WIDTH NO-BREAK SPACE的字符,它的编码为FEFF。而FEFF在UCS中是不存在的字符,所以不应该出现在实际的字节流传输中。所以UCS规范建议我们在传输字节流前,先传输字符ZERO WIDTH NO-BREAK SPACE。因此,如果接受方接受到FEFF,则表明该字节流为大尾序;若为FFFE,则表明该字节流为小尾序。因此,ZERO WIDTH NO-BREAK SPACE又被称作BOM。 UTF-8没有像UTF-16大小尾序的表示方法,所以是不需要BOM来表明字节顺序的,但是也可以用BOM来表明编码方式,字符ZERO WIDTH NO-BREAK SPACE的UTF-8编码是EF BB BF,这也是UTF-8有含有BOM和没有BOM的原因。
更多编码方案
GBK等