代码改变世界

编码与解码

2013-06-30 00:41  阿普的博客  阅读(271)  评论(0编辑  收藏  举报

编码发展历史:
1、汉字的编码的发展:
早期计算机使用7位的ASCII编码,为了处理汉字,设计了用于简体中文的GB2312和用于繁体中文的big5。
GB2312支持的汉字太少,于是扩增为GBK。GB18030是进一步扩增的版本。在这些版本中,ASCII、GB2312、GBK、GB18030是向下兼容的,即同一个字符在各个版本中的编码是相同的。

2、由于各个语言都存在独立的编码系统(比如日语、俄语等),系统之间进行文档交流是很困难的。比如,对于多语言文档,必须在语言切换时添加说明(下面使用俄语编码...下面使用日语编码)。于是,Unicode被设计出来解决这个问题。
  unicode使用2个字节来表示每个字符,能表示2^16个字符,包含了世界上的几乎所有字符。因此统一了编码方式。但是为了兼容现有的系统(比如只支持GB2312的设备),还需要把它转换为遗留编码系统。
新设计的unicode与GBK等编码的并不兼容,即同一个字符在两种编码之后,结果不相同,原因显而易见。


3、事实证明,对可以用ASCII表示的字符使用UNICODE并不高效,因为UNICODE比ASCII占用大一倍的空间,而对ASCII来说高字节的0对他毫无用处。为了解决这个问题,就出现了一些中间格式的字符集,他们被称为通用转换格式,即UTF(Universal Transformation Format)。目前存在的UTF格式有:UTF-7, UTF-7.5, UTF-8,UTF-16, 以及 UTF-32。

4、UCS可以看作是”Unicode Character Set”的缩写。UCS规定了用多少个字节表示各种文字。
UCS有两种格式:UCS-2和UCS-4。顾名思义,UCS-2就是用两个字节编码,UCS-4就是用4个字节编码。

5、UCS规定了怎么用多个字节表示各种文字。怎样传输这些编码,是由UTF(UCS Transformation Format)规范规定的,
常见的UTF规范包括UTF-8、UTF-7、UTF-16。

UTF-8使用一至四个字节为每个字符编码:

   1、128个US-ASCII字符只需一个字节编码(Unicode范围由U+0000至U+007F)。
   2、带有附加符号的拉丁文、希腊文、西里尔字母、亚美尼亚语、希伯来文、阿拉伯文、叙利亚文及它拿字母则需要二个字节编码(Unicode范围由U+0080至U+07FF)。
   3、其他基本多文种平面(BMP)中的字符(这包含了大部分常用字)使用三个字节编码。
   4、其他极少使用的Unicode 辅助平面的字符使用四字节编码。
   
6、UTF的字节序和BOM

UTF -8以字节为编码单元,没有字节序的问题。UTF-16以两个字节为编码单元,在解释一个UTF-16文本前,首先要弄清楚每个编码单元的字节序。例如收到一个“奎”的Unicode编码是594E,“乙”的Unicode编码是4E59。如果我们收到UTF-16字节流“594E”,那么这是“奎”还是 “乙”?

Unicode规范中推荐的标记字节顺序的方法是BOM(Byte Order Mark)。BOM是一个有点小聪明的想法:

在UCS 编码中有一个叫做”ZERO WIDTH NO-BREAK SPACE”的字符,它的编码是FEFF。而FFFE在UCS中是不存在的字符,所以不应该出现在实际传输中。UCS规范建议我们在传输字节流前,先传输字符”ZERO WIDTH NO-BREAK SPACE”。

这样如果接收者收到FEFF,就表明这个字节流是Big-Endian的;如果收到FFFE,就表明这个字节流是Little-Endian的。因此字符”ZERO WIDTH NO-BREAK SPACE”又被称作BOM。

UTF -8不需要BOM来表明字节顺序,但可以用BOM来表明编码方式。字符”ZERO WIDTH NO-BREAK SPACE”的UTF-8编码是EF BB BF(读者可以用我们前面介绍的编码方法验证一下)。所以如果接收者收到以EF BB BF开头的字节流,就知道这是UTF-8编码了。

Windows就是使用BOM来标记文本文件的编码方式的。