目录
前言
计算机中一个基本的存储单元是字节(byte),但是由于人类世界的语言众多,要让计算机理解我们的语言,必须要经过一个拆分和翻译的过程,这个过程就是编码;
一个字节(byte),为 8 个 bit,表示的字符范围为 0~255 个;
1个字节无法完全表示人类的符号,所以使用了一个新的数据结构 char,char 到 byte 必须编码。
常见的编码格式
编码格式就是翻译方式,定义了转化的规则。
Unicode:ISO 试图创建的一个超语言字典,想让世界上所有语言可以通过这个相互翻译
1. ASCII码
可表示 128 个字符,单字节编码,使用一个字节的低 7 位表示,可以通过键盘输入并打印出来,0~31 控制字符(换行、回车...),32~126 打印字符。
2. ISO-8859-1
ISO-8859-1 至 ISO-8859-15,为 ISO 在 ASCII 码基础上扩展而来,ISO-8859-1 涵盖大多数西欧语言字符,应用最广泛,单字节编码,可表示 256 个字符。
3. GB2312
双字节编码,全称《信息技术 中文编码字符集》,编码范围 A1~F7,A1~A9 符号区(682 符号),B0~F7 汉字区(6763 汉字)。
4. GBK
扩展 GB2312,编码和 GB2312 兼容,编码范围 8140~FEFE(去掉 XX7F),一共 23940 个码位,可以表示 21003 个汉字。
5. GB18030
可能是单字节、双字节或者四字节编码,与 GB2312 兼容,使用并不广泛。
6. UTF-16
具体定义了 Unicode 字符在计算机中的存取方法,使用两个字节表示 Unicode 转化格式,采用定长的表示方法,每两个字节表示一个字符,简化了字符串的操作,Java使用 UTF-16作为内存的字符串存储格式。
7. UTF-8
使用 UTF-16 编码,原先只需一个字节的字符现在也需要用两个字节表示,增大了存储空间和网络传输的流量,而 UTF-8 采用一种变长技术,每个编码区域有不同的字码长度,不同类型的字符可以由 1~6 个字节组成。
UTF-8编码规则:
如果是一个字节,最高位(第8位)为0,表示这个字符为 ASCII 字符;
如果是一个字节,以 11 开头,比如 110xxxxx,代表双字节UTF-8字符的首字节;
如果是一个字节,以10开始,表示不是首字节,需向前查找得到当前字符的首字节。
几种编码格式的比较
讨论编码:ISO-8859-1、GB2312、GBK、UTF-16、UTF-8
针对语言:中文
ISO-8859-1:
黑洞现象:把不认识的字符吸收掉,一些中文字符经过 ISO-8859-1 编码会丢失信息。
注意:大部分 Java 框架默认字符集编码为 ISO-8859-1。
GB2312:
GB2312 字符集有一个从char 到 byte 的码表,不同的字符编码从这个码表找到字符对应的字节,如果查到的码位值大于 0xff,则为双字节(高 8 位第一个字节,低 8 位第二个字节),否则为单字节。
GBK:
GBK 和 GB2312 编码算法一样,GBK 编码兼容 GB2312 编码,但是 GBK 包含汉字字符更多
UTF-16:
将字符的高位和低位拆分成两个字节,编码效率高,规则简单。
存在的问题:采用顺序编码,无法对单个字符的编码值进行校验,浪费了存储空间(对单字节字符)
UTF-8:
对单字节范围内的字符使用1个字节表示,汉字采用3个字节表示
比较:
就 GBK 和 GB2312 来说,GBK 可表示中文字符的范围大,应选择 GBK;
UTF-8 与 GBK 和 GB2312 不同,不需要查码表,效率高,采用 UTF-8;
UTF-8 和 UTF-16 都是处理 Unicode 编码,但是编码规则不同,相对来说,UTF-16 编码效率较高,字符(char)和字节(byte)相互转换更简单,进行字符串操作也更好,适合在磁盘、内存中使用,提供 char 和byte 之间的快速切换;UTF-8更适合网络传输,网络传输易损坏字节流,UTF-8 使用单字节存储 ASCII 字符,损坏单个字符不会影响后面字符。