仔细读读字符集(Unicode、ASCII、GB2312)和字符编码(GB2310、UTF-8、UTF-16、GBK、)和转换规则

首先弄明白几个概念:
字符(Character):在计算机和电信技术中,一个字符是一个单位的字形、类字形单位或符号的基本信息,字符是各种文字和符号的总称,包括各国家文字、标点符号、图形符号、数字等,例如:A,B,1,2,&,%等这些都称为字符。
字符集(Character set):是多个字符的集合,字符集种类较多,每个字符集包含的字符个数不同,例如:ASCII字符集、GB2312字符集,unicode字符集等
字符编码(Character encoding)也称字集码,是把字符集中的字符编码为指定集合中某一对象(例如: 比特模式、自然数序列、8位组或者电脉冲),以便文本在计算机中存储和通过通信网络的传递。也就是说字符编码是一套法则,将字符集中的每一个字符,映射为 另一个集合(比特模式、自然数序列、8位组或者电脉冲)中。

字符集和字符编码的关系,以ASCII来说就是:A->0x01000001,B->0x01000010…… 即将字符集中每一个字符对应一个比特序列

为什么会有这么多字符集呢和字符编码呢?
这个原因很简单,不同的国家一般都有自己的文字和符号,ASCII只能满足一些一些英语国家的需要,其他的国家当然需要自己的字符集来表示自己的文字,于是有了不同的字符集和编码。
GB2312字符集和编码:
GB2312-80全称是《信息交换用汉字编码字符集·基本集》是由中国国家标准总局1980年发布,1981年5月1日开始实施的一套国家标准。基本集 共收入汉字6763个和非汉字图形字符682个。整个字符集分成94个区,每区有94个位。每个区位上只有一个字符,因此可用所在的区和位来对汉字进行编 码,称为区位码。
把换算成十六进制的区位码加上2020H,就得到国标码。国标码加上8080H,就得到常用的计算机机内码。
为什么要加2020H呢?
    因为ASCII码编码中分控制信号编码和有型字符编码,前32个是控制码,如回车、换行、退格等,为避开这些控制码,国标码规定在区位码的基础上加20H(即32的16进制数)
为什么要加上8080H呢?
   是因为在计算机中ASCII码和汉字机内码是共存的,那么我们就要来区分它们,我们知道ASCII码的最高位是0,所以我们将汉字机内码的最高位置为1, (80H二级制表示就为10000000)表示区别所以计算机在判断ASCII码还是汉字机内码的时候,只需要判断它们的最高位就行了

GBK(Chinese Internal Code Specification)全称《汉字内码扩展规 范》,是对GB2312编码的扩展,因此完全兼容GB2312-80标准。GBK 亦采用双字节表示,总体编码范围为 8140-FEFE,首字节在 81-FE 之间,尾字节在 40-FE 之间,剔除 xx7F 一条线。总计 23940 个码位,共收入 21886 个汉字和图形符号,其中汉字(包括部首和构件)21003 个,图形符号 883 个。

中国自己搞了一套编码,其他国家当然也各自做了自己的编码,这样在本地自己使用是没有问题的,一旦在网络上传输,就会出现各种乱码,也就是我们常见的?????????等等
于是Unicode字符集和编码出现了。

Unicode编码:
Unicode 是基于通用字符集UCS(Universal Character Set)的标准来发展,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。Unicode实际上 是一个字符集。Unicode用数字0-0x10FFFF来映射这些字符,最多可以容纳1114112个字符,或者说有1114112个码位。码位就是可 以分配给字符的数字。UTF-8、UTF-16、UTF-32都是将数字转换到程序数据的编码方案。
在Unicode字符集中的某个字符对应的代码值,称作代码点(CodePoint),用16进制书写,并加上U+前缀。 Unicode定义的字符集已经超过16位所能表达的范围,把所有这些CodePoint分成17个代码平面(Code Plane)
U+0000 ~ U+FFFF划入基本多语言平面(Basic MultilingualPlane,简记为BMP);
其余划入16个辅助平面(Supplementary Plane),代码点范围U+10000 ~ U+10FFFF。


UTF-8:采用变长字节 (1 ASCII, 2 希腊字母, 3 汉字, 4 平面符号) 表示,网络传输, 即使错了一个字节,不影响其他字节,而双字节只要一个错了,其他也错了,具体如下:
如果只有一个字节则其最高二进制位为0;如果是多字节,其第一个字节从最高位开始,连续的二进制位值为1的个数决定了其编码的字节数,其余各字节均以10开头。UTF-8最多可用到6个字节。

将UTF8对Unicode编码的方式如下:
单字节:0xxxxxxx
双字节:110xxxxx 10xxxxxx  
三字节:1110xxxx 10xxxxxx 10xxxxxx
四字节:11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
例如"汉"字的Unicode编码是6C49。6C49在0800-FFFF之间,所以要用3字节模板:1110xxxx 10xxxxxx 10xxxxxx。将6C49写成二进制是:0110 1100 0100 1001,将这个比特流按三字节模板的分段方法分为0110 110001 001001,依次代替模板中的x,得到:1110-0110 10-110001 10-001001,即E6 B1 89,这就是其UTF8的编码。

这里说下:一般采用三种方式来决定文本的字符集和编码:
1.检测文件头标识,2.提示用户选择,3.根据一定的规则猜测
最标准的途径是检测文本最开头的几个字节,开头字节 Charset/encoding,如下表:
EF BB BF UTF-8
FE FF UTF-16/UCS-2, little endian
FF FE UTF-16/UCS-2, big endian
FF FE 00 00 UTF-32/UCS-4, little endian.
00 00 FE FF UTF-32/UCS-4, big-endian.

UTF-16
UTF-16比起UTF-8,好处在于大部分字符都以固定长度的字节 (2字节) 储存,但UTF-16却无法兼容于ASCII编码。
UTF-16编码以16位无符号整数为单位。注意是16位为一个单位,不表示一个字符就只有16位。现在机器上的unicode编码一般指的就是UTF- 16。绝大部分2个字节就够了,但是不能绝对的说所有字符都是2个字节。这个要看字符的unicode编码处于什么范围而定,可能是2个字节,也可能是4 个字节。所以要决定UTF-8或UTF-16哪种编码比较有效率,还要视所使用的字符的分布范围而定
对U+0000.. U+D7FF以及U+E000.. U+FFFF的编码
UTF-16与UCS-2对这个范围内的CodePoint进行编码,采用单个16bit长的CodeUnit,数值等价于对应的Code Point。BMP中的这些Code Point是仅有的可以被UCS-2表示的Code Point。
对U+10000.. U+10FFFF的编码 辅助平面(Supplementary Planes)中的CodePoint,在UTF-16中被编码为一对16bit长的Code Unit(即32bit,4Bytes),称作代理对(surrogate pair)。

UTF-16辅助平面代理对与Unicode的对应关系如下表:

Lead \ Trail 0xDC00  0xDC01  …  0xDFFF
0xD800 U+10000 U+10001 U+103FF
0xD801 U+10400 U+10401  U+107FF
0xDBFF  U+10FC00  U+10FC01  U+10FFFF

具体编码方式:

1.Code Point减去0x10000, 得到的值是长度为20bit(0..0xFFFFF);
2.由1得到数值的高位的10比特的值(值范围为0..0x3FF)加上0xD800得到第一个Code Unit或称作高位代理(high surrogate)或前导代理(lead surrogate)。取值范围是0xD800..0xDBFF。
3.由1得到数值的低位的10比特的值(值范围为0..0x3FF)加上0xDC00得到第二个Code Unit或称作低位代理(low surrogate)或后尾代理(trail surrogate)。取值范围是0xDC00..0xDFFF。
这样,这个范围内的字符就被编码成了一个代理对[lead surrogate,trail surrogate]:两个16bits的Code Unit,取值范围分别是0xD800..0xDBFF和0xDC00..0xDFFF。而BMP中得到的Code Unit的范围是0x0000..0xFFFF(0xD800..0xDFFF是保留的,不包含其中),所以这三个区段是相互不重叠的,在解码时很容易实 现。
UTF-16解码[高位代理+低位代理]得到的Code Unit对与Code Point的对应关系如上表所示。


UTF-32
UTF-32和Unicode码表基本一一对应,固定四个字节。但是如果统一用4个字节,占用空间太浪费,UTF-32通常会是其它编码的二到四倍

Pingbacks are open.

Trackback URL

Comments

1 Comments

  • fortnite v bucks hack
    21 Jul 2019, 13:28 | Reply
    Wow, awesome blog layout! How long have you been blogging for? you make blogging glance easy. The full look of your website is fantastic, as well as the content material! my webpage
Post your comment

cancel reply