1. UTF 简介

UTF(UCS/Unicode/Universal Transformation Format)有多种 transform 方式, 常见的有 UTF-8/UTF-16/UTF-32.

出现原因:

  1. 事实证明, 对可以使用 ASCII 表示的字符使用 Unicode 并不高效, 因为 Unicode 使用 2 个字节. 为了解决这个问题, 出现了一些中间格式字符集, 被称为通用转换格式. 可以这么说Unicode 是编码方式, 它规定了编码(即哪个字符在什么码位),而 UTF-8 等是 Unicode实现方式, 它出于节省空间或其它目的来对 Unicode 所占空间进行转换.

  2. 另外我目前的理解是: Unicode 码原生不支持与任何码表兼容, 包括ASCII.
    举例: UCS-2 以 2 字节为单位而 ASCII 以 1 个字节为单位, 试想英文 a : 0110,00010000,0000 0110,0001 计算机是不会认为他们是一样的. 而如果使用UTF-8那么, 编码就会相同为 1 个字节 0110,0001.

2. UTF-8

UTF-8(将 8 bit, 即一个字节看作一个单位): 使用 1~4 个字节来编码. 如, 当用 UTF-8 存储 ASCII 字符时就只用 1 个字节,相似其它字符按一定算法转换为 1~4 个字节. 算法如下

  1. UCS-2编码(16进制) UTF-8 字节流(二进制)
  2. 0000 - 007F 0xxxxxxx
  3. 0080 - 07FF 110xxxxx 10xxxxxx
  4. 0800 - FFFF 1110xxxx 10xxxxxx 10xxxxxx

比如 字的 Unicode6C49, 那么就需要使用 3 字节的格式,写出来是 1110 0110,1011 0001,1000 1001, 也即 E6 B1 89. 4字节算法没写.

3. UTF-16

3.1. 实现方式

UTF-16 将 16 bit(2 字节) 看作一个单位. 设计之初为固定宽度的 16 bit(2 byte) 编码格式(可以表示 plane 0 所有), 随着时间发展为了支持增补字符 (其它plane) 设置了代理对机制(surrogate pair): 把范围 U+10,0000~U+10,FFFF 内的字符使用一对 (2 个) 16 bit 来表示.

算法如下:

  1. 对于的UCS码的小于0x10000的部分(plane 0中的),UTF-16编码==UCS-2对应的16位无符号整数.
  2. 不小于0x10000的部分使用代理对(具体怎么代理不探究了)

3.2. big-endian / little-endian

UCS-2 是一个编码方案, 而 UTF-16 是一个实际使用的转换格式. 因为 UTF-16 一个单元是16 bit, 但计算机只能表示 8 bit 为单位, 所以分解 (解析显示时) 这个单元时这两个 8 bit 谁先谁后就也有说法了 (即一个单位中 2 个字节的字节顺序问题), 高字节到低字节称为大尾 big-endian, 反之称为小尾 little-endian. UTF-32 也需要考虑这个问题, 而 UTF-8 以 8 bit 为单位, 故而没有在单位中排字节顺序的需要.

例如: 已知 Unicode 编码是 4E 59, 当我们收到一个 Unicode 编码 59 4E 时, 我们是该翻译为奎还是乙呢? 解决方案:

使用 Unicode 的推荐字节顺序标记方法 BOM(Byte Order Mark).
它的方法是: UCS 中有个字符叫 "ZERO WIDTH NO-BREAK SPACE", 它编码为 FE FF, 还有个字符 FF FE 在UCS中不存在。
UCS 规范建议我们在传输字节流最前, 先传输字符 FE FF 表明字节流是 Big-Endian; 传输 FF FE 表明字节流是 Little-Endian.

UTF-8 不需要用 BOM 来表明字节顺序,但是可以用 BOM 来表明编码方式. 字符”ZERO WIDTH NO-BREAK SPACE” 的 UTF-8 编码是 EF BB BF. 如果接受到已此开头的字节流, 那么好了, 你知道它是 UTF-8 编码的.

你好Unicode 编码: 4F 60, 59 7D. 下图是用 UTF-8 编码的文本: 你好 两个字的编码:

EF BB BF E4 BD A0 E5 A5 BD

使用 UTF-16 Big-endian你好 编码:

EF FF 4F 60 59 7D

3.3 UTF-8 与 UTF-16 对比

比起UTF-8, UTF-16 的好处在于大部分字符都是用固定长度 (2 byte) 存储 (如果长度固定是你的要求的话).