谈谈 Unicode 编码,简要解释 UCS、UTF、BMP、BOM 等名词
这是一篇程序员写给程序员的趣味读物。所谓趣味是指可以比较轻松地了解一些原来不清
楚的概念,增进知识,类似于打 RPG 游戏的升级。整理这篇文章的动机是两个问题:
问题一:
使用 Windows 记事本的“另存为”,可以在 GBK、Unicode、Unicode big endian 和 UTF-8 这
几种编码方式间相互转换。同样是 txt 文件,Windows 是怎样识别编码方式的呢?
我很早前就发现 Unicode、Unicode big endian 和 UTF-8 编码的 txt 文件的开头会多出几个字
节,分别是 FF、FE(Unicode),FE、FF(Unicode big endian),EF、BB、BF(UTF-8)。
但这些标记是基于什么标准呢?
问题二:
最近在网上看到一个 ConvertUTF.c,实现了 UTF-32、UTF-16 和 UTF-8 这三种编码方式的
相互转换。对于 Unicode(UCS2)、GBK、UTF-8 这些编码方式,我原来就了解。但这个程
序让我有些糊涂,想不起来 UTF-16 和 UCS2 有什么关系。
查了查相关资料,总算将这些问题弄清楚了,顺带也了解了一些 Unicode 的细节。写成一
篇文章,送给有过类似疑问的朋友。本文在写作时尽量做到通俗易懂,但要求读者知道什
么是字节,什么是十六进制。
0、big endian 和 little endian
big endian 和 little endian 是 CPU 处理多字节数的不同方式。例如“汉”字的 Unicode 编码是
6C49。那么写到文件里时,究竟是将 6C 写在前面,还是将 49 写在前面?如果将 6C 写在
前面,就是 big endian。如果将 49 写在前面,就是 little endian。
“endian”这个词出自《格列佛游记》。小人国的内战就源于吃鸡蛋时是究竟从大头(Big-
Endian)敲开还是从小头(Little-Endian)敲开,由此曾发生过六次叛乱,一个皇帝送了命,另
一个丢了王位。
我们一般将 endian 翻译成“字节序”,将 big endian 和 little endian 称作“大尾”和“小尾”。
1、字符编码、内码,顺带介绍汉字编码
字符必须编码后才能被计算机处理。计算机使用的缺省编码方式就是计算机的内码。早期
的计算机使用 7 位的 ASCII 编码,为了处理汉字,程序员设计了用于简体中文的 GB2312
和用于繁体中文的 big5。
GB2312(1980 年)一共收录了 7445 个字符,包括 6763 个汉字和 682 个其它符号。汉字区的
内码范围高字节从 B0-F7,低字节从 A1-FE,占用的码位是 72*94=6768。其中有 5 个空位