Unicode To UTF16 编码与解码
UTF-16 小解
UTF-16(16-bit Unicode Transformation Format)是一种针对Unicode的可变长度字符编码。见 UTF-16。
Unicode 的编码空间可划分为17个平面(plane),每个平面包含 65536 个码位,计17个平面。第一个平面称为基本多语言平面(Basic Multilingual Plane, BMP),或称第零平面(Plane 0),其他平面称为辅助平面(Supplementary Planes)。
Unicode 基本平面与辅助平面
Plane | Number of bytes | First code point | Last code point |
---|---|---|---|
基本平面 | 2 | U+0000 | U+FFFF |
辅助平面 | 4 | U+10000 | U+10FFFF |
其中:
- 基本平面(BMP)包含了大部分常用字,如大部分的汉字(Unicode范围由U+0800至U+FFFF)。
- 辅助平面 emoji 表情等(Unicode范围由U+0800至U+FFFF)。
转化过程
- 将数据转化为 unicode 的 codePoint,在 JS 中可借助于
str.codePointAt(0)
- 如果 unicode 小于
U+10000
,则直接返回,为 UTF-16 编码 - 如果 unicode 大于
U+10000
,则分为两个 UTF-16 编码(codePoint - 0x10000) / 1024 + 0xD800, ((codePoint - 0x10000) % 1024) + 0xDC00
,更详细的描述见下示例
如,🍉
- 根据
'🍉'.codePointAt().toString(16)
得出其十六进制为0x1f349
- 根据
0x1f349
减去0x10000
,结果为0x0f349
,二进制为0000 1111 0011 0100 1001
,并分为两部分0000 1111 00
(0x003c) 和11 0100 1001
(0x0349) - 添加
0xd800
到上值,以形成高位:0xd800 + 0x003c = 0xd83c
- 添加
0xdc00
到下值,以形成低位:0xdc00 + 0x0349 = 0xdf49
API
JS
在 Javascript 中,可借助于 iconv-lite 进行转化
// Encodingiconv.encode(str, 'utf16')
// Decodingiconv.decode(buffer, 'utf16')
Python
> '山月'.encode('utf16').hex()'fffe715c0867'
> bytes.fromHex('fffe715c0867').decode('utf16')山月