Unicode标准为每一个字符提供一个唯一的数字,而不用区分平台、语言等因素。

The Unicode Standard provides a unique number for every character, no matter what platform, device, application or language.

基本概念

在开始学习之前,我们需要先了解本文所涉及到的一些基本概念。

抽象字符(Abstract character):用于组织、控制或者表示文本数据的信息单元。

  • 抽象字符没有具体的形式,不应与图像字符(glyph)混淆。
  • 抽象字符不一定对应于人们所认知的“字”,不应与字素(grapheme)混淆。
  • 不能被Unicode标准直接编码的抽象字符通常可以通过组合字符序列来表示。

抽象字符序列(Abstract character sequence):一个或多个抽象字符的有序序列。

Unicode编码空间(Unicode codespace):十六进制0x0~0x10FFFF之间的整数。

码位(Code point):Unicode编码空间中的任意值。

编码字符(Coded character):当抽象字符被映射或者分配到编码空间中特定的码位时,它就被称为编码字符。

码位

码位是Unicode标准中很重要的一个概念。它的取值范围是十六进制的0x0~0x10FFFF,换算成十进制是0~1114111,共计1114112个。

需要注意的是,一个单一的抽象字符可能对应一个以上的码位。例如,Ω既可以表示大写的希腊字母Omega,码位是U+03A9,也可以表示物理学中的欧姆符号,码位是U+2126

  1. >>> '\u03a9'
  2. 'Ω'
  3. >>> '\u2126'
  4. 'Ω'

单个抽象字符也可以由一系列码位的序列来表示。例如,é的码位是U+00E9,它也可以由小写字母e(码位为U+0065)和 ́Combining Acute Accent)(码位为U+0301)组合而成。

  1. >>> '\u00e9'
  2. 'é'
  3. >>> '\u0065\u0301'
  4. 'é'

在Unicode标准中,码位的表示方法通常是使用它们的十六进制,并加上U+前缀。

码位的类型

码位的分类方法多种多样。我们通过下表来阐明Unicode标准使用的七种类型和一些术语。

基本类型 简要描述 是否分配给抽象字符 码位范围
图形(Graphic) 字母、标记、数字、标点符号、符号和空格
格式(Format) 不可见但是影响相邻字符。包括行、段落分割符
控制(Control) Unicode标准以外的协议或标准定义的用法 U+0000~U+001F,U+007F,U+0080~U+009F,共计65个
私用(Private-use) Unicode标准以外的私有协议定义的用法
代理 (Surrogate) 永久预留给UTF-16编码方案 不允许分配 U+D800~U+DFFF,共计2048个
非字符(Noncharacter) 永久预留给内部使用 U+FDD0~U+FDEF,所有以FFFE或者FFFF结尾的码位,共计66个
保留(Reserved) 预留给将来使用

我们需要格外注意代理(Surrogate)类型,理解他有助于我们学习UTF-16。它总共包含2048个码位,码位空间为U+D800~U+DFFF。它由引发出两个新的概念:

高位代理(High-Surrogate):U+D800~U+DBFF范围内的码位,共计1024个。

低位代理(Low-Surrogate):U+DC00~U+DFFF范围内的码位,共计1024个。

关于它们更多的内容,稍后结合UTF-16再讨论。

编码方案

在介绍具体的编码方案之前,我们先明确一些新的基本概念。

Unicode标量值(Unicode scalar value):除去高位代理和低位代理之外,所有的Unicode码位,也就是U+0000~U+D7FF和U+E000~U+10FFFF范围内的码位。

编码单元(Code unit):最小的比特位组合,表示用于交换或处理的编码文本单元。Unicode标准中定义,UTF-8使用8比特的编码单元,UTF-16使用16比特的编码单元,UTF-32使用32比特的编码单元。

编码单元序列(Code unit sequence):一个或多个编码单元的有序序列。

UTF-32

UTF-32将每个Unicode标量值映射成一个无符号的32比特的编码单元,数值与Unicode标量值相同,这是一种定长的编码方案。

注意,UTF-32无法编码U+D800~U+DFFF之间的码位,因为它们不属于Unicode标量值。

  1. >>> '\ud800'.encode('utf32')
  2. Traceback (most recent call last):
  3. File "<stdin>", line 1, in <module>
  4. UnicodeEncodeError: 'utf-32' codec can't encode character '\ud800' in position 0: surrogates not allowed

UTF-16

UTF-16将Unicode标量值中U+0000~U+D7FFU+E000~U+FFFF范围内的码位映射成一个无符号的16比特的编码单元,数值与Unicode标量值相同。将U+10000~U+10FFFF范围内的码位映射成一个代理对,所谓的代理对就是上文提到的高位代理和低位代理。UTF-16是一种定长和变长兼顾的编码方案。

下表阐明了UTF-16的编码方式。

Unicode标量值 UTF-16
xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
000u uuuu xxxx xxxx xxxx xxxx 1101 10ww wwxx xxxx 1101 11xx xxxx xxxx

其中, wwww = uuuuu - 1

重点分析使用代理对的情况,一个代理对包含一个高位代理编码单元和一个低位代理编码单元,都是16比特的。其中高位代理的范围是U+D800~U+DBFF,转换成二进制,它的格式应该是1101 10xx xxxx xxxx,低位代理的范围是U+DC00~U+DFFF,转换成二进制,它的格式应该是1101 11xx xxxx xxxx。

至此,我们还剩下20位可以填充。我们将码位减去U+10000,再从右到左依次填充进去,就能得到UTF-16的编码。

以字符

Unicode标准以及其常见的编码方案的更多相关文章

  1. 刨根究底字符编码之八——Unicode编码方案概述

    Unicode编码方案概述   1. 前面讲过,随着计算机发展到世界各地,于是各个国家和地区各自为政,搞出了很多既兼容ASCII但又互相不兼容的各种编码方案.这样一来同一个二进制编码就有可能被解释成不 ...

  2. 从Java String实例来理解ANSI、Unicode、BMP、UTF等编码概念

    转(http://www.codeceo.com/article/java-string-ansi-unicode-bmp-utf.html#0-tsina-1-10971-397232819ff9a ...

  3. Windows 记事本的 ANSI、Unicode、UTF-8 这三种编码模式有什么区别?

    [梁海的回答(99票)]: 简答.一些细节暂无精力查证,如果说错了还请指出. 一句话建议:涉及兼容性考量时,不要用记事本,用专业的文本编辑器保存为不带 BOM 的UTF-8. * * * 如果是为了跨 ...

  4. 转:Python常见字符编码及其之间的转换

    参考:Python常见字符编码 + Python常见字符编码间的转换 一.Python常见字符编码 字符编码的常用种类介绍 第一种:ASCII码 ASCII(American Standard Cod ...

  5. ascii、unicode、utf、gb等编码详解

    很久很久以前,有一群人,他们决定用8个可以开合的晶体管来组合成不同的状态,以表示世界上的万物.他们看到8个开关状态是好的,于是他们把这称为"字节".再后来,他们又做了一些可以处理这 ...

  6. ASCII、Unicode、GBK和UTF-8字符编码的区别联系

    转自http://dengo.org/archives/901 很久很久以前,有一群人,他们决定用8个可以开合的晶体管来组合成不同的状态,以表示世界上的万物.他们看到8个开关状态是好的,于是他们把这称 ...

  7. ASCII、Unicode、GBK和UTF-8字符编码的区别联系(转载)

    ASCII.Unicode.GBK和UTF-8字符编码的区别联系 转载自:http://dengo.org/archives/901 很久很久以前,有一群人,他们决定用8个可以开合的晶体管来组合成不同 ...

  8. ASCII、Unicode、GBK和UTF-8字符编码的区别联系[转]

    http://dengo.org/archives/901 这是我看过的最好的一篇讲述编码的文章 很久很久以前,有一群人,他们决定用8个可以开合的晶体管来组合成不同的状态,以表示世界上的万物.他们看到 ...

  9. Java基础--常见计算机编码类型

    计算机编码指电脑内部代表字母或数字的方式,常见的编码方式有:ASCII编码,GB2312编码(简体中文),GBK,BIG5编码(繁体中文),ANSI编码,Unicode,UTF-8编码等. 1.ASC ...

随机推荐

  1. TCP/IP||UDP广播和多播

    1.概述 广播和多播应用于UDP,TCP是一个面向连接协议,意味着分别运行与两个主机内的两进程间存在一个连接,在考虑多个主机内的共享通信网络,每个以太网帧包含源主机和目的主机以太网地址(48bit), ...

  2. mysql主从之LVS+keepalived+双主MySQL 负载均衡

    LVS(Linux Virtual Server)即Linux 虚拟服务器,是一个的开源负载均衡项目,目前LVS 已经被集成到Linux 内核模块中.LVS 是四层负载均衡,也就是说建立在OSI 模型 ...

  3. 009 Ceph RBD增量备份与恢复

    一.RBD的导入导出介绍 Ceph存储可以利用快照做数据恢复,但是快照依赖于底层的存储系统没有被破坏 可以利用rbd的导入导出功能将快照导出备份 RBD导出功能可以基于快照实现增量导出 二.RBD导出 ...

  4. Java正则表达式学习与记录

    转载自:http://www.runoob.com/java/java-regular-expressions.html 正则表达式定义了字符串的模式,用于搜索.编辑或处理文本. 1.正则表达式中字符 ...

  5. 「Poj1845」Sumdiv 解题报告

    题面戳这里 啥都别看,只是求 \(a^b\)所有的因数的和 思路: 真没想到! 其实我们可以先将\(a^b\)分解成质因数的 因为\(a^b\)的因数肯定是\(a^b\)的质因数在一定的条件下相乘而成 ...

  6. docker练习-堆栈

    介绍 分布式应用程序层次结构的顶部:堆栈. 堆栈是一组相互关联的服务,它们共享依赖关系,并且可以协调和缩放在一起. 单个堆栈能够定义和协调整个应用程序的功能(尽管非常复杂的应用程序可能希望使用多个堆栈 ...

  7. linux中的ldd命令简介

    转载自:http://blog.csdn.net/stpeace/article/details/47069215 在linux中, 有些命令是大家通用的, 比如ls, rm, mv, cp等等, 这 ...

  8. Scala实践6

    1  if表达式 Scala中if...else..表达式是有返回值的,如果if和else返回值类型不一样,则返回Any类型. scala> val a3=10 a3: Int = 10 sca ...

  9. 79.纯 CSS 创作单元素麦当劳金拱门 Logo(自创)

    效果地址:https://scrimba.com/c/cN3P6nfr 原理:两个椭圆,颜色部分为边框,下一半被伪元素覆盖. 感想:看了一眼大神的,代码比我的还少,得研究研究去. HTML code: ...

  10. Spring Boot2 系列教程 (十六) | 整合 WebSocket 实现广播

    前言 如题,今天介绍的是 SpringBoot 整合 WebSocket 实现广播消息. 什么是 WebSocket ? WebSocket 为浏览器和服务器提供了双工异步通信的功能,即浏览器可以向服 ...