Unicode OverView
Foundation
Unicode:是一种字符编码标准,旨在为全球所有文字和符号提供唯一的编码。
统一编码:不同于其他字符集,Unicode 为每一个字符赋予唯一的码点,避免了字符冲突。
全球化支持:使不同语言和符号能够在计算机系统中一致地表示和处理。
互操作性:解决不同字符集之间的兼容性问题,使得数据交换和文档传输更加顺畅。
起源:Unicode 由国际 Unicode 联盟(Unicode Consortium)于1987年开始开发。
Unicode 字符集
字符
字符是指书写系统中的基本单位,包括字母、数字、符号、标点符号等。
Unicode支持的字符类型包括:
- 基本拉丁字母(Basic Latin):包括英文字母、数字、基本的标点符号等。例如:A, B, C, 1, 2, 3, !, ?, .
- 拉丁字母扩展(Latin Extended):包括带有变音符号的拉丁字母,如à, é, ñ等。
- 标点符号和符号(Punctuation and Symbols):各种标点符号、数学符号、货币符号等。例如:$, %, +, =, ©, ™, ♠, ♥
- 数字(Numbers):阿拉伯数字、罗马数字、上标和下标数字等。例如:123, Ⅳ, ², ₃
- 表情符号(Emojis):如😀, 😂, ❤️, 🎉等。
- 特殊字符和符号(Special Characters and Symbols):如•, ‼, ※, †等。
- 音乐符号(Musical Symbols):如𝄞, 𝄢, 𝄪等。
- 数学字母数字符号(Mathematical Alphanumeric Symbols):如𝒜, 𝒞, ℬ, ℰ, 𝔄, 𝔊等。
- 中文汉字(CJK Unified Ideographs):包括中文、日文、韩文的常用汉字。例如:你, 好, 日本, 韓國
- 其他语自然语言等。。。
码点(Code Point)
编码字符集是一组字符,每个字符都被分配了唯一的数字。编码字符集的单位称为码点。码位值表示字符在编码字符集中的位置。
码点(码位)是 Unicode 字符集中每个字符的唯一标识,通常表示为 U+XXXX 的形式,其中 XXXX 是十六进制数字。
码点范围从 U+0000 到 U+10FFFF,其中:
- U+0000 到 U+007F:ASCII 字符集,包含基本的英文字母、数字和控制字符。
- U+0080 到 U+FFFF:包含各种语言的字符和符号,涵盖拉丁字母扩展、希腊字母、汉字等。
- U+10000 到 U+10FFFF:称为辅助平面,包含较少使用的字符和符号,如历史文字、表情符号等。
码元(Code Unit)
码元是编码字符数据所用的基本单元。不同的编码方式使用不同大小的码元。例如:
- UTF-16 使用一个或两个 16 位的码元表示一个字符。
- UTF-8 使用一个到四个 8 位的码元表示一个字符。
- UTF-32 使用一个 32 位的码元表示一个字符。
编码范围
基本多文种平面 (BMP) 是从 U+0000 到 U+FFFF,包含大多数常用拉丁字母、希腊字母、汉字、标点符号、控制字符。
辅助平面:分为多个不同的平面,每个平面有特定的用途:
- 辅助多文种平面 (SMP):从 U+10000 到 U+1FFFF,包含历史文字、音乐符号、数学符号等。
- 辅助标点平面 (SIP):从 U+20000 到 U+2FFFF,主要用于扩展汉字字符。
- 辅助专用区平面 (SSP):从 U+E0000 到 U+EFFFF,供私人使用的字符区域。
- 字符备用区 (PUA):从 U+F0000 到 U+10FFFF,供用户自定义字符。
Unicode 编码方式
Unicode 编码方式是指将 Unicode 字符转换为字节序列的方式。
常见的 Unicode 编码形式有 UTF-8、UTF-16 和 UTF-32。不同的编码形式在处理效率、存储空间和兼容性方面有所不同。
UTF-8
UTF-8(8-bit Unicode Transformation Format)是一种用于表示 Unicode 字符的可变长度字符编码。 它是一种广泛使用的编码方式,特别适用于互联网和电子邮件,因为它向后兼容 ASCII 并且能够有效地编码所有 Unicode 字符。
编码规则
UTF-8 使用 1 至 4 个字节编码 Unicode 字符,根据字符的不同范围选择不同的字节数:
- 1字节:用于 ASCII 码字符(U+0000 至 U+007F)。
- 2字节:用于大部分拉丁字母及其他语言的字符(U+0080 至 U+07FF)。
- 3字节:用于几乎所有的基本多语言平面字符(U+0800 至 U+FFFF)。
- 4字节:用于补充平面字符(U+10000 至 U+10FFFF)。
具体的编码规则如下:
- 1 字节:0xxxxxxx (7 位)
- 2 字节:110xxxxx 10xxxxxx (5 + 6 = 11 位)
- 3 字节:1110xxxx 10xxxxxx 10xxxxxx (4 + 6 + 6 = 16 位)
- 4 字节:11110xxx 10xxxxxx 10xxxxxx 10xxxxxx (3 + 6 + 6 + 6 = 21 位)
Note
x
的补充规则:是将转换后的二进制从高位到低位依次补充。具体看下列例子,
编码示例
示例1: 字符 “A” UTF-8 编码
- 获取其Unicode码点:
- 转换为二进制:0100 0001
- 获取所需要的字节数:U+0041在 U+0000 到 U+007F范围内,因此需要一个字节
- 得到对应字节的编码规则以及按高位到低位补码:0xxxxxxx 0100 0001
- UTF-8表示:
示例1: 字符 “你” UTF-8 编码
- 获取其Unicode码点:
- 转换为二进制:0100 1111 0110 0000
- 获取所需要的字节数:在 U+0800 至 U+FFFF范围内,因此需要三个字节
- 得到对应字节的编码规则以及按高位到低位补码:1110xxxx 10xxxxxx 10xxxxxx 11100100 10111101 10100000
- UTF-8表示:
UTF-16
UTF-16(16-bit Unicode Transformation Format)是一种将 Unicode 字符编码为16位宽字符的编码方式。 它可以编码整个 Unicode 字符集( 到 ),并且使用一种可变长度的编码格式来处理不同的字符范围。
Note
在早期的计算机系统中,字符通常使用 8 位(一个字节)表示,最多可以表示 256 个字符(如 ASCII 编码)。 但是,随着计算机的普及,特别是在需要处理多种语言的国际环境中,256 个字符远远不够。因此,Unicode 标准被引入, 试图为每种语言的所有字符分配一个唯一的代码点。
为了处理 Unicode 字符集中的大量字符,尤其是那些超出 8 位表示范围的字符,16 位宽字符被引入。 这种表示方式使用 16 位(2 字节)来表示一个字符,可以表示最多 65536(216)个不同的字符。
基本原理
- 基本多文种平面 (BMP)
- 范围: U+0000 到 U+FFFF
- BMP内的字符用一个16位单元表示
- 补充平面
- 范围:U+10000 到 U+10FFFF
- 超出BMP的字符使用一对16位单元表示,称之为代理对
编码规则
-
BMP内的字符 BMP 内的字符直接用一个 16 位单元表示,其值与 Unicode 码点相同。
-
代理对 对于补充平面字符(码点大于 U+FFFF),UTF-16 使用两个 16 位单元:
- 高代理项(High Surrogate):从 U+D800 到 U+DBFF。
- 低代理项(Low Surrogate):从 U+DC00 到 U+DFFF。
代理对的计算
对于一个 Unicode 码点 U(大于 U+FFFF),其代理对的计算步骤如下:
- 减去 U+10000,得到一个 20 位的数。
- 将这个 20 位的数分成高 10 位和低 10 位。
- 高 10 位加上 U+D800,得到高代理项。
- 低 10 位加上 U+DC00,得到低代理项。
编码示例
示例1: 字符 ”😊“(U+1F60A) UTF-16 编码过程
- 确定字符Unicode码点
- 码点为U+1F60A
- 减去
0x10000
: 0x1F60A - 0x10000 = 0xF60A
- 分解为高10位和低10位
- 高10位:(0x0F60A >> 10) & 0x3FF = 0x03C
- 低10位:0x0F60A & 0x3FF = 0x0AA
- 计算高代理项和低代理项:
- 高代理项:0xD800 + 0x03C = 0xD83D
- 低代理项:0xDC00 + 0x0AA = 0xDE0A
- UTF-16编码结果
- 代理对:
0xD83D 0xDE0A
Pitfall
0xF60A >> 10
意味着将码点 0xF60A 向右移动 10 位。在二进制操作中,右移 10 位相当于将最高的 10 位移除,剩下的低位。 对于码点 0xF60A,移位后得到的结果是 0x3D。& 0x3FF
是为了确保结果不超过 10 位二进制数的范围, 在二进制操作中,& 0x3FF 是为了保留最低的 10 位。
使用JavaScript进行UTF-16编码
function utf16Encode(codePoint) {if (codePoint <= 0xFFFF) {// Basic Multilingual Plane (BMP) characterreturn String.fromCharCode(codePoint);} else {// Supplementary Plane character (U+10000 - U+10FFFF)codePoint -= 0x10000;let highSurrogate = 0xD800 + (codePoint >> 10);let lowSurrogate = 0xDC00 + (codePoint & 0x3FF);return String.fromCharCode(highSurrogate, lowSurrogate);}}
UTF-32
UTF-32 是一种将 Unicode 字符编码为固定长度的 32 位整数(4 字节)的编码形式。 每个 Unicode 码点直接映射到一个 32 位整数,因此所有字符的编码长度是固定的 4 字节。 这使得 UTF-32 的计算和处理非常简单,因为你可以直接按 4 字节来读写和索引字符。
主要特点:
- 固定长度:每个字符始终占用 4 个字节,不像 UTF-8 或 UTF-16 那样使用可变长度的编码。这个特性使得字符的索引和处理非常简单。
- 直接映射:每个 Unicode 码点直接映射到一个 32 位整数,编码和解码过程不需要复杂的算法。
- 空间效率低:因为每个字符都占用 4 个字节,所以 UTF-32 在空间利用率上较低,特别是对于主要使用基本多文种平面(BMP,码点范围为 U+0000 到 U+FFFF)的文本来说,UTF-32 比 UTF-8 或 UTF-16 要浪费更多的存储空间。
编码示例
示例1: 字符 ”A“(U+1F60A) UTF-32 编码过程
- Unicode码点是U+0041
- UTF-32编码为:U+00000041
使用场景
UTF-32 通常用于内存空间不是问题且需要高效随机访问字符的应用场景。例如:
- 某些特定的系统和工具可能内部使用 UTF-32 进行字符串处理,以便简化代码和提高处理速度。
- 某些高性能计算环境中,UTF-32 的固定长度特性可能有助于简化并加速文本处理算法。
差异以及对比
特性 | UTF-8 | UTF-16 | UTF-32 |
---|---|---|---|
编码长度 | 可变长度(1-4 字节) | 可变长度(2 或 4 字节) | 固定长度(4 字节) |
编码范围 | U+0000 到 U+10FFFF | U+0000 到 U+10FFFF | U+0000 到 U+10FFFF |
字符表示 | ASCII 字符占 1 字节,多字节表示非 ASCII 字符 | BMP 字符占 2 字节,辅助平面字符占 4 字节 | 所有字符占 4 字节 |
空间效率 | 高效,特别是对 ASCII 字符 | 中等,对于 BMP 字符较高效 | 低,所有字符均占 4 字节 |
处理复杂度 | 较高,需要处理可变长度编码 | 较高,需要处理代理对 | 简单,固定长度 |
字符索引 | 较复杂,需要遍历字符 | 较复杂,需要处理代理对 | 简单,直接按 4 字节索引 |
应用场景 | 网络传输、文件存储、系统接口 | 内存表示、文件存储、某些网络协议 | 内存表示、某些高性能计算 |
优点 | 高效的空间利用率,特别适合 ASCII 文本 | 对 BMP 字符高效,广泛支持 | 编码和解码简单,固定长度便于处理 |
缺点 | 处理复杂,字符索引困难 | 处理代理对复杂,空间利用率较低 | 空间利用率低,浪费内存 |
Unicode 常用工具
字符映射表
字符映射表工具用于查看和搜索 Unicode 字符及其属性。常见的字符映射表工具包括:
- Unicode Character Table: 提供完整的 Unicode 字符列表,支持按字符名称、码点、块进行搜索。
- Unicode.org Code Charts: 提供官方的 Unicode 代码图,按块和范围显示字符,包含详细的字符信息。
字符转换工具
字符转换工具用于在不同编码之间转换字符。常见的字符转换工具包括:
- Online Unicode Converter: 支持将文本在 UTF-8、UTF-16、UTF-32 和其他编码之间相互转换。
- JavaScript Unicode Converter: 使用 JavaScript 库将字符在不同编码之间转换。
字符检查工具
字符检查工具用于验证字符的有效性,检查字符属性和编码问题。常见的字符检查工具包括:
- Unicode Character Inspector: 检查 Unicode 字符的详细信息,包括码点、名称、类别、脚本等。
- Unicode Character Properties: 提供 Unicode 字符的属性信息,支持按字符搜索。
编码检测工具
编码检测工具用于检测文本的编码方式,以便正确解码。常见的编码检测工具包括:
- dencode: 检测文本的编码方式等信息
除此之外,onlinetools 包含了多种的关于Unicode的工具。