UTF-16 编码简介

Last Modified: 2022/11/09

编码说明

UTF-16 使用一个或两个未分配的 16 位代码单元的序列对 Unicode 代码点进行编码,码点在 U+0000 ~ U+FFFF 区间的字符编码为一个相同值的 16 位单元。

码点在 U+0000 ~ U+FFFF 区间的字符为基本字符集,可以看出基本字符集的编码非常简单,直接一对一编码为 16 位即可。但是之后 Unicode 码点增加到 U+10FFFF,其中码点在 U+10000 ~ U+10FFFF 之间的字符无法直接映射为 16 位编码。

U+10000 ~ U+10FFFF 之间的字符为增补字符,这部分字符采用两个 16 位完成编码。看到用两个 16 位编码,有些同学可能会有疑问,如何区分两个 16 位表示的是两个字符还是一个字符?很好的问题,这个在后面回答。

增补字符编码方式

U+10000 ~ U+10FFFF 采用代理对(surrogates pairs)的方式编码。代理对划分为为高代理码点,码点范围 0xD800 ~ 0xDBFF 和低代理码点,码点范围:0xDC00 ~ 0xDFFF。也就是说 U+10000 ~ U+10FFFF 之间的字符编码使用两个码点编码,一个码点来自高代理码点区间,另外一个码点来自低代理码点区间。

举例来说:增补字符集的第一个字符, 采用的代理对为:(0xD800, 0xDC00)。这里需要特别说明的是代理码点都是未分配的,也就是这些码点并没有用来编码基本字符集中的字符,因此不用担心无法区分两个 16 位到底表示的是一个字符还是两个字符。

代理对的计算方法

  • 将增补字符的码点值减去 0x10000,得到一个 20 位的二进制数;
  • 将得到的 20 位的二进制数拆分为高 10 位和低 10 位;
  • 高 10 位加上 0xD800 得到第一个代理码点,即高代理码点;
  • 低 10 位加上 0xDC00 得到 第二个代理码点,即低代理码点;
  • 将得到的高代理码点和低代理码点组成一对(拼接起来),便得到了增补字符的 UTF-16 编码。

拿音乐字符 𝄞 举例,它的代码点为 U+1D11E

1、0x1D11E - 0x10000 = 0xD11E = 0000110100 0100011110
2、20 位的高 10 位和低 10 位对应的 16 进制分别为:0x0034 和 0x011e
2、高代理:0x0034 + 0xD800 = 0xD834
3、低代理:0x011e + 0xDC00 = 0xDD1E

有问题吗?点此反馈!

温馨提示:反馈需要登录