1. ASCII码
1> ASCII码不包括我们输入法中的"特殊字符"和"数学字符"等,他们都属于扩展ASCII 字符
2. GBK编码
GBK实际上是ASCII的中文扩展编码,其规则是:
1> 如果第一个字节的大于127(0x7F, 0111 1111,即最高位为0),则表示从这个字节开始的2个字节是表示一个汉字,否则,则是一个英文ASCII码
2> GBK是兼容ASCII的
3> GBK的汉字编码占用2个字节
4> 这类编码方式统称为做 “DBCS“(Double Byte Charecter Set 双字节字符集)
3. Unicode编码
Unicode是为了解决ASCII的各类扩展编码方式不统一的问题(比如GBK和台湾的汉字编码就不兼容),而制定的采用多字节统一编码世界所有字符的编码方案,所以Unicode能显示各国的字符编码
1> Unicode编码包括UCS-2, UCS-4,分别用2, 4个字节表示一个字符,通用的是UCS-2
2> 由于多个字节在内存中的储存设计到字符顺序的问题
3> Unicode表示ASCII码时,是将高位字节全置为0,所以Unicode和ASCII是不兼容的
Magic Header(by byte) | Exmaple("中":0x4E2D) | |
小尾(LE) | FF, FE | FF, FE, 2D, 4E |
大尾(BE) | FE, FF | FE, FF, 4E, 2D |
4. UTF-8
UCS-2表示英文字母会浪费一个字节,而世界上大部分的资料都是用英文的,所以用Unicode编码进行文件传输和保存的时候就极为浪费带宽和硬盘, 因此就有了UTF-8, UTF-16的出现来拯救世界
UTF :(UCS Transfer Format)
1> UTF-8:UTF-8是一种变长的编码方式,可以用1~4个字节表示一个字符
2> UTF-8的原码还是Unicode,只是其将Unicode进行了格式化编码,转化方式:
2.1 单字节的字符(如英文),字节的第一位设为0,对于英语,UTF-8码只占用一个字节,和ASCII码完全相同;
2.2 需用n个字节的字符(n>1),第一个字节的前n位设为1,第n+1位设为0,后面字节的前两位都设为10,这n个字节的其余空位填充该字符unicode码(2进制的),高位用0补足。
如格式化字符:"中"(0x4E2D, 0100 1110 0010 1101)
(1) "中"占用2个字节,因为UTF-8需要多的bit来做标记,所以至少需要多余2个字节的空间来转UTF-8,先设n=3
(2) 3个字节各自的标记bit如下:
1 : 1110 0000
2 : 1000 0000
3 : 1000 0000
(3) 我们发现剩下的空的bit位数 = 4 + 6 + 6 = 16 = 2字节,刚好够放一个Unicode,依次将"中"(0100 1110 0010 1101)的2进制bit放入
1 : 1110 0100 0xE4
2 : 1011 1000 0xB8
3 : 1010 1101 0xAD
(4) 虽然Unicode填入UTF-8的模板没说是大尾还是小尾,而是用我们正常看2进制数的顺序填入的,但这个顺序其实是一个大尾(0x4E放在前面转bit)
3> Windows中,会使用BOM来标记编码顺序,UTF-8由于没有编码顺序,Windows就用BOM = EF BB BF来表示UTF-8编码,但很多系统和软件中是不认这个BOM的
4> "®"字符的Unicode编码是0x00AE,在UTF-8编码中是采用2个字节的模板来编码的:C2 AE = 1100 0010 1010 1110,抽取出来就是0 0010 10 1110 = 000 1010 1110,然后高位补0 = 0000 0000 1010 1110 = 0xAE,也就是说Unicode编码高位为00的字符,在UTF-8中都可以用2字节的模板来编码,可以节省一个字节