转载

Java编码ASCII、GB2312、GBK、Unicode、UTF-8、UTF-16 编码方式详解

1 ASCII

American Standard Code for Information Interchange。最早最通用的单字节编码系统,因为发明时间早,所以ASCII编码表的设计较为简单。

结构

  • ASCII表是单字节字符表,此表中一个(英文)字符用一个字节表示
  • 在ASCII中从00000000(第0个)~00011111(第31个)前32被用来作为控制字符表示各种类似:响铃、退格、换页等控制操作
  • 在ASCII中从00101111(第32个)~01111111(第127个)表示基本符号(!,@。%…)、数字(1,2,3…)、英文字母
  • ASCII表中一共有127个字符,后面的剩余空闲的字节没有被使用。

2 GB2312

GB2312是1981年开始实施的一套汉字处理的编码方案,GB是“国标”的意思,GB2312是对ASCII进行了扩展,在原来ASCII的基础上扩充了6000多个汉字和600多个其他字符,是我们使用的较早的一个汉字编码版本。

结构

GB2312用一个字节表示一个英文字符和一些基本符号和半角符号,用两个字节表示一个汉字和全角符号和一些我们日常使用的符号。
GB2312利用了ASCII的127个字符之后空余的部分,增添了6000多种常用汉字。
数值小于127的字节表示ASCII中原有字符,两个连续数值都大于127的字节表示一个汉字字符。
使用GB2312编码,当读取到一个数值上小于127的字节时当作一个ASCII中原有的字符处理。读到一个数值大于127的字节时会继续读取下一个字节,下一个字节的数值也必定是大于127,将两个大于127的字节一起组合形成一个字符。

3 GBK

GB2312有局限性,只能表示6000个字符,GBK是对GB2312的升级,GBK与GB2312非常相似,唯一的不同:

结构

使用GBK编码,当读取到一个数值上小于127的字节时当作一个ASCII中原有的字符处理。读到一个数值大于127的字节时必定会继续读取下一个字节,下一个字节的数值无需大于127,将两个字节一起组合形成一个汉字字符。
仅仅是一点微小的变化,让GBK在2312的基础上多增加了20000余个字符,GBK也是我们最常用的中文编码表。相比较UTF-8,GBK需要的空间小,如果我们工作的受众对象是汉语对象,使用GBK没有问题,但需注意java语言使用unicode编码,有可能会存在转换问题导致乱码,使用需谨慎。

4 Unicode

我们的GB2312和GBK都是在ASCII的基础上修改而来,利用了ASCII只使用127个字节的特点,而全世界其他的国家也是如此操作,导致了各个国家之间存在复杂的编码转换问题。而unicode的出现直接一次性扫清了所有障碍,原因很简单:unicode编码表中包含了世界上所有国家的所有字符和符号的编码。
unicode这种称呼是不专业的,这种统一世界的编码方式叫做:Universal Multiple-Octet Coded Character Set,简称:UCS。我们在习惯上将它叫做unicode。unicode编码是一种概念,在最新的规范中,所有的字符一概使用四个字节表示,网上有很多说unicode用两个字节表示一个字符是不对的,Unicode字符分为17组编排,0x0000 至 0xFFFF,而每平面拥有65536个码位,共1114112个。

5 UTF-8

unicode编码是一种概念,实际上真正实现了unicode编码的是被使用次数最多的UTF标准(UCS Transfer Format)。在UTF标准中现今最常用的是UTF-8。UTF-8是unicode编码的一种实现。

结构

UTF-8灵活性很强,用1~4个字节表示一个字符。
当字符在ASCII中可以被表示时,UTF-8编码方式就用一个字节来表示它。
在UTF-8中汉字用3个字符来表示。
unicode中所有的字符一概使用两个字节表示。从unicode到UTF-8并不是直接的对应,而是要过一些算法和规则来转换。

6 UTF-16

UTF-16不是简单的把UTF-8的范围扩大了一倍,UTF-16和UTF-8是彻底不同的两种编码概念。

结构

在绝大多数情况下,UTF-16中一个字符固定使用两个字节编码,一个字符两个字节是UTF-16编码的概念。
在极少数情况下也会出现三个字节表示一个字符的情况。
由于UTF-16固定使用两个字节表示一个字符,所以UTF-16不能与ASCII兼容。
在不同的机器中UTF-16存在因存储方式不同(大端法和小端法)导致数据有误,因此存在UTF16-LE和UTF16-BE两种UTF16的变体。
相比较UTF-8,在存储中文方面,UTF16更加结合空间。
UTF-16容错情况比UTF-8好,因为UTF-16稳定使用两个字节编码,如果数据错误不会连代其他数据被读错,而UTF-8是变长编码,可能导致后面的字符全部错误。
UTF-16广泛应用在各种系统中。

7 UTF-32

UTF-32可以说是“真正”的unicode编码,unicode用四个字节表示一个字符的特点在UTF-32中实现了,理论上这样根本不需要复杂的分配字节的方法,只需要每个字符一一对应即可,而且UTF-32的超大容量装得下任何的字符。但是问题也就在这里,一个字符需要四个字节太过于奢侈,UTF-32并不是一个很常用的编码方法。

正文到此结束
本文目录