ASCII、GB2312、GBK、Unicode、UTF-8、UTF-16 编码方式比较分析

实际上在日常工作开发中,中文乱码是经常出现的一类问题。下面介绍一下ASCII、GB2312、GBK、Unicode、UTF-8、UTF-16、UTF-32编码的原理以及不同点和区别。

ASCII

ASCII的英文翻译是:American Standard Code for Information Interchange,也就是说,ASC后的II实际上是两个首字母I的缩写,而不是罗马数字中的2。ASCII是最早最通用的单字节编码系统,因为发明时间早,所以ASCII编码表的设计较为简单。

结构

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

GB2312

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

结构

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

GBK

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

结构

  1. 使用GBK编码,当读取到一个数值上小于127的字节时当作一个ASCII中原有的字符处理。读到一个数值大于127的字节时必定会继续读取下一个字节,下一个字节的数值无需大于127,将两个字节一起组合形成一个汉字字符。

仅仅是一点微小的变化,让GBK在2312的基础上多增加了20000余个字符,GBK也是我们最常用的中文编码表。相比较UTF-8,GBK需要的空间小,如果我们工作的受众对象是汉语对象,使用GBK没有问题,但需注意java语言使用unicode编码,有可能会存在转换问题导致乱码,使用需谨慎。

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个。

UTF-8

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

结构

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

UTF-16

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

结构

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

UTF-32

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

你可能感兴趣的:(java,一周一篇Java概念)