1. ASCII码
ASCII (American Standard Code for Information Interchange, 美国标准信息交换代码),是基于拉丁字母的一套编码系统。主要用于显示现代英语和其它西欧语言。它是现今最通用的单字节编码系统。
单个字节能够表示256个不同的字符,只是 ASCII 仅仅使用了当中低于\x80
(即最高位字节为0)的一半来表示全部的英文字符以及一些控制字符,因此 ASCII 码的实际取值范围为0x00
到0x7f
之间,一共128个字符。
2. 多字节字符集MBCS
ASCII字符集中仅仅含有英文字符,不能满足其它语言的需求。于是非常多语言就制定了一套自己的编码。由于 ASCII 是单字节的,能表示的字符数量太少,因此这些编码非常多都使用多个字节来表示单个字符。比如 GBK 等。 这些编码的规则都比較类似: 假设第一个字节是\x80
下面。则仍然表示 ASCII 字符,而假设是\x80
以上,则跟下一个字节一起(共两个字节)表示一个字符。
IBM发明了一个叫Code Page
的概念,将这些编码都收入囊中并分配页码,GBK 是第936页,也就是CP936
。所以,也能够使用CP936
表示 GBK 。
这些各种语言自己制定的编码统称 MBCS (Multi-Byte Character Set)。眼下都是用了双字节,所以有时候也称为 DBCS (Double-Byte Character Set)。
必须明白的是,MBCS 并非指某一种特定的编码,Windows里依据你设定的区域不同。MBCS 代表不同的编码,而Linux里无法使用 MBCS 作为编码。
在Windows中你看不到 MBCS 这几个字符。由于微软使用了 ANSI 这个称呼,记事本的另存为对话框里编码 ANSI 就是 MBCS 。
在中文简体 Windows 默认的区域设定中。ANSI 代表 GBK 编码。
3. Unicode
由于各种不同的 MBCS 编码互相不兼容。使用、转换起来非常不方便,于是便有了 Unicode 。
Unicode (万国码、国际码、统一码、单一码)是计算机科学领域里的一项业界标准。它对世界上大部分的文字系统进行了整理、编码,使得电脑能够用更为简单的方式来呈现和处理文字。
Unicode 发展由非营利机构统一码联盟负责,该机构致力于让Unicode方案替换既有的字符编码方案。由于既有的方案往往空间非常有限,亦不适用于多语环境。
Unicode 备受认可,并广泛地应用于电脑软件的国际化与本地化过程。有非常多新科技,如可扩展置标语言、Java编程语言以及现代的操作系统,都採用 Unicode 编码。
最初的Unicode标准UCS-2
使用两个字节表示一个字符,一共能表示 256×
个字符。不久后又有人认为还是太少了,于是出现了用4个字节表示一个字符的UCS-4
标准。
UCS (Unicode Character Set)仅仅是字符相应码位的一张表而已。
详细怎样传输和储存字符则是由 UTF (UCS Transformation Format)来指定。
一開始直接使用 UCS 的码位来保存字符。这就是UTF-16,比方汉
这个字的码位是6C49
,则直接使用\x6C\x49
保存(UTF-16-BE,BE
指Big Endian),或是倒过来使用\x49\x6C
保存(UTF-16-LE,LE
指Little Endian)。
可是这样的保存方式在保存英文字符时,会浪费非常多存储空间( ASCII 保存一个字符仅仅须要一个字节)。于是变有了 UTF-8。
UTF-8 是一种变长并且兼容 ASCII 的字符编码,在 UTF-8 中 ASCII 字符仍然使用相同的一个字节表示。这使得原来处理 ASCII 字符的软件无须或仅仅须做少部分改动,就可以继续使用。因此,它逐渐成为电子邮件、网页及其它存储或发送文字的应用中。优先採用的编码。
UTF-8 使用一至六个字节为每一个字符编码(虽然如此。2003年11月 UTF-8 被RFC 3629
又一次规范,仅仅能使用原来 Unicode 定义的区域。U+0000
到U+10FFFF
。也就是说最多四个字节):
- 128个 US-ASCII 字符仅仅需一个字节编码(Unicode 范围由
U+0000
至U+007F
). - 带有附加符号的拉丁文、希腊文、西里尔字母、亚美尼亚语、希伯来文、阿拉伯文、叙利亚文及它拿字母则须要两个字节编码( Unicode 范围由
U+0080
至U+07FF
)。 - 其它基本多文种平面( BMP) 中的字符(这包括了大部分经常使用字,如大部分的汉字)使用三个字节编码(Unicode 范围由
U+0800
至U+FFFF
)。 - 其它极少使用的 Unicode 辅助平面的字符使用四至六字节编码(Unicode 范围由
U+10000
至U+1FFFFF
使用四字节,Unicode 范围由U+200000
至U+3FFFFFF
使用五字节,Unicode 范围由U+4000000
至U+7FFFFFFF
使用六字节)。
对上述提及的第四种字符而言,UTF-8 使用四至六个字节来编码似乎太耗费资源了。但 UTF-8 对全部经常使用的字符都能够用三个字节表示,并且它的还有一种选择。UTF-16 编码,对前述的第四种字符相同须要四个字节来编码。所以要决定 UTF-8 或 UTF-16 哪种编码比較有效率。还要视所使用的字符的分布范围而定。
另外值得一提的是 BOM (Byte Order Mark)。我们在储存文件时,文件使用的编码并没有保存,打开时则须要我们记住原先保存时使用的编码并使用这个编码打开,这样一来就产生了很多麻烦。UTF 则引入了 BOM 来表示自身编码,假设一開始读入的几个字节是当中之中的一个,则代表接下来要读取的文字使用的编码是相应的编码:
BOM | BYTES |
---|---|
BOM_UTF8 |
\xef\xbb\xbf |
BOM_UTF16_LE |
\xff\xfe |
BOM_UTF16_BE |
\xfe\xff |
并非全部的编辑器都会写入 BOM ,但即使没有 BOM,Unicode 还是能够读取的,仅仅是像 MBCS 的编码一样。须要另行指定详细的编码。否则解码可能会失败。
绝大多数编辑器在没有BOM时都是以 UTF-8 作为默认编码读取。
即使是保存时默认使用 ANSI (MBCS)的记事本。在读取文件时也是先使用 UTF-8 測试编码。假设能够成功解码。则使用 UTF-8 解码。这个别扭的做法造成了一个BUG:假设你新建文本文件并输入姹塧
然后使用 ANSI 保存。再打开就会变成 汉a
。
參考资料: