UTF-16究竟是怎么编码的

1.

首先要注意的是,代理Surrogate是专属于UTF-16编码方式的一种机制,UTF-8和UTF-32是不用代理的。

如前文所述,为了让UTF-16能继续编码基本平面后面的增补平面中的码点值,于是扩展了UTF-16编码方式。

具体的扩展方法就是为其增加了代理机制,用两个对应于基本平面码点(即BMP代理区中的码点)的16位码元来表示一个增补平面码点,这两个用来表示一个增补平面码点的特殊16位码元就被称为“代理对”。

如果要用简单的一句话来概括,就是——所有大于0xFFFF的码点值(即增补平面码点编号,范围为0x10000~0x10FFFF,十进制为65536~1114111;注意,0xFFFF是十六位二进制数的最大值的十六进制表示)要编码成UTF-16编码方式的话,就必须使用代理机制(也就是用代理对来表示)。

2.

在UTF-16编码方式中,被合起来称为”代理对“的这两个16位码元就其中的任一单个码元而言,其实就直接对应于基本平面BMP中的某一个码点(即BMP中每一个码点的值必然对应于一个16位码元的值,因为基本平面中的码点总数为2^16=65536个,而16位码元能表示的值也等于2^16=65536个)。

这样一来,就产生了冲突:某个UTF-16码元到底是用于表示基本平面字符的码元,还是用于表示增补平面字符的代理对中的代理码元?

因此,为避免冲突,这些被用作“代理”的任一码元所对应的码点在基本平面中均未定义字符,即均没有指定字符。

“代理”的真实含义或许就在于此:用两个基本平面中未定义字符的码点合起来“代为署理”增补平面中的码点。

因此,基本平面中这些用作“代理”的码点区域就被称之为“代理区(Surrogate Zone)”,其码点编号范围为0xD800~0xDFFF(十进制55296~57343),共2048个码点。

3.

增补平面一共有16个平面(即第2平面~第17平面),码点编号范围为0x10000~0x10FFFF(十进制为65536~1114111,码点总数为1048576个)。用两个代理码元表示,第一个码元的取值范围为0xD800~0xDBFF(二进制为1101 1000 0000 0000 ~ 1101 1011 1111 1111,十进制为55296 ~ 56319),第二个码元的取值范围为0xDC00~0xDFFF(二进制为1101 1100 0000 0000 ~ 1101 1111 1111 1111,十进制为56320 ~ 57343)。

因此,增补平面的第一个码点的编号0x10000其UTF-16编码就是0xD800 0xDC00(即0x10000经UTF-16编码后的码元序列为0xD800 0xDC00),其余类推。展现为二进制形式后如下:

====代理码元1====     ====代理码元2====

1101 10pp ppxx xxxx      1101 11xx xxxx xxxx

其中代理码元1中的110110、代理码元2中的110111是定数,p、x是变数。去掉定数后组合起来就是pppp xxxx xxxx xxxx xxxx,共20位(2^20=1048576),刚好能够表示增补平面中的全部码点(0x10000~0x10FFFF,共1048576个)。其中pppp共4位,表示16个增补平面之一的编号(2^4=16);紧接着的16位x表示某个增补平面内的某个码点(2^16=65536,而65536*16=1048576)。

4.

按照上面的编码方式,代理对里面的两个代理码元分别称之为高16位代理码元(或称为lead surrogates引导代理、前导代理),和低16位代理码元(或称为trail surrogates尾随代理、后尾代理)。

由于引导代理和尾随代理的值分别在0xD800~0xDBFF(十进制为55296 ~ 56319)之间和0xDC00~0xDFFF(十进制为56320 ~ 57343)之间,所以首尾两个代理总共可以组合出(56319-55296+1)*(57343-56320+1)=1048576个代理对,也就是总共可以表示1048576个增补码点,而目前Unicode标准所确定的16个增补平面的码点总和也就是65536*16=1048576个。

笨笨阿林原创文章,转载请注明出处)

5.

从增补平面的码点值通过基本平面中的代理对编码为增补平面字符的码元序列的具体算法如下:

1) 增补平面中的码点值(0x10000~0x10FFFF,二进制为0001 0000 0000 0000 0000~1 0000 1111 1111 1111 1111,对应的字符名称为U+10000~U+10FFFF)减去0x10000(二进制为0001 0000 0000 0000 0000),可得到20位长的比特组(值的范围为0x00000~0xFFFFF,二进制为0000 0000 0000 0000 0000 ~ 1111 1111 1111 1111 1111);

2)将得到的20位长的比特组分拆为两部分:高位10比特和低位10比特;

3)20位长的比特组中的高位10比特(值的范围为0x000~0x3FF,二进制为00 0000 0000~11 1111 1111)加上0xD800(二进制为1101 1000 0000 0000),得到第一个代理码元即引导代理(值的范围是0xD800~0xDBFF,二进制为1101 1000 0000 0000 ~ 1101 1011 1111 1111);

4)20位长的比特组中的低位10比特(值范围也是0x000~0x3FF,二进制为00 0000 0000~11 1111 1111)加上0xDC00(二进制为1101 1100 0000 0000),得到第二个代理码元即尾随代理(值的范围是0xDC00~0xDFFF,二进制为1101 1100 0000 0000 ~ 1101 1111 1111 1111);

5)将引导代理与尾随代理按前后顺序组合在一起成为“代理对”,就得到了增补平面字符的码元序列。

例如,增补平面中码点值为10437(字符名称为U+10437)的字符(

刨根究底字符编码之十四——UTF-16究竟是怎么编码的的更多相关文章

  1. 刨根究底字符编码之十六——Windows记事本的诡异怪事:微软为什么跟联通有仇?(没有BOM,所以被误判为UTF8。“联通”两个汉字的GB内码,其第一第二个字节的起始部分分别是“110”和“10”,,第三第四个字节也分别是“110”和“10”)

    1. 当用一个软件(比如Windows记事本或Notepad++)打开一个文本文件时,它要做的第一件事是确定这个文本文件究竟是使用哪种编码方式保存的,以便于该软件对其正确解码,否则将显示为乱码. 一般 ...

  2. 刨根究底字符编码之十二——UTF-8究竟是怎么编码的

    UTF-8究竟是怎么编码的 1. UTF-8编码是Unicode字符集的一种编码方式(CEF),其特点是使用变长字节数(即变长码元序列.变宽码元序列)来编码.一般是1到4个字节,当然,也可以更长. 为 ...

  3. 刨根究底字符编码之十一——UTF-8编码方式与字节序标记

    UTF-8编码方式与字节序标记 一.UTF-8编码方式 1. 接下来将分别介绍Unicode字符集的三种编码方式:UTF-8.UTF-16.UTF-32.这里先介绍应用最为广泛的UTF-8. 为满足基 ...

  4. 刨根究底字符编码之十三——UTF-16编码方式

    UTF-16编码方式 1. UTF-16编码方式源于UCS-2(Universal Character Set coded in 2 octets.2-byte Universal Character ...

  5. 刨根究底字符编码之—UTF-16编码方式

    在网上已经转悠好几天了, 这篇文章让我知道了UTF-16的前世今生, 感谢作者https://cloud.tencent.com/developer/article/1384687 1. UTF-16 ...

  6. 刨根究底字符编码之五——简体汉字编码方案(GB2312、GBK、GB18030、GB13000)以及全角、半角、CJK

    简体汉字编码方案(GB2312.GBK.GB18030.GB13000)以及全角.半角.CJK   一.概述 1. 英文字母再加一些其他标点字符之类的也不会超过256个,用一个字节来表示一个字符就足够 ...

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

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

  8. 刨根究底字符编码之四——EASCII及ISO 8859字符编码方案

    EASCII及ISO 8859字符编码方案   1. 计算机出现之后,从美国发展到欧洲,由于欧洲很多国家中所用到的字符中,除了基本的美国也用的那128个ASCII字符之外,还有很多衍生的拉丁字母等字符 ...

  9. JAVA之旅(二十四)——I/O流,字符流,FileWriter,IOException,文件续写,FileReader,小练习

    JAVA之旅(二十四)--I/O流,字符流,FileWriter,IOException,文件续写,FileReader,小练习 JAVA之旅林林总总也是写了二十多篇了,我们今天终于是接触到了I/O了 ...

随机推荐

  1. [原创]MongoDB_Sharding

    Mongo Sharding:本示例搭建了三个副本集作为三个分片的sharding集群,其中master,slave,factershi三台同网段的内网主机.前期规划和原理分析省略,可根据具体配置推导 ...

  2. R与并行计算(转)

    文章摘要 本文首先介绍了并行计算的基本概念,然后简要阐述了R和并行计算的关系.之后作者从R用户的使用角度讨论了隐式和显示两种并行计算模式,并给出了相应的案例.隐式并行计算模式不仅提供了简单清晰的使用方 ...

  3. GitBook 使用

    介绍 GitBook是一个基于Node.js的命令行工具,可使用 Github/Git和Markdown来制作精美的电子书,GitBook 并非关 Git的教程. 导出格式有PDF.HTML等,需要添 ...

  4. sChart.js:一个小型简单的图表库

    介绍 sChart.js 作为一个小型简单的图表库,没有过多的图表类型,只包含了柱状图.折线图.饼状图和环形图四种基本的图表.麻雀虽小,五脏俱全.sChart.js 基本可以满足这四种图表的需求.而它 ...

  5. 探讨SQL Server并发处理存在就更新七种解决方案

    前言 本节我们来讲讲并发中最常见的情况存在即更新,在并发中若未存在行记录则插入,此时未处理好极容易出现插入重复键情况,本文我们来介绍对并发中存在就更新行记录的七种方案并且我们来综合分析最合适的解决方案 ...

  6. 数据库插入数据失败,log提示不能将值 NULL 插入列 'id'

    已经记不住具体的log信息了,意思就是ID如果没有设置为自增长的情况下就不能插入数据,而建表时ID字段是设置为"not null",所以就不能顺利插入数据. 解决方法有两种: ①建 ...

  7. VR全景智慧城市,完美的将虚拟与现实结合

    很多人都粗浅的认为,VR虚拟智慧城市只是简单的将智慧城市和虚拟现实相结合的产物,这样的VR虚拟智慧城市看起来更像是个VR内容产品,而非城市建设成果.但是我们换个角度来思考的话,现在很多VR虚拟智慧城市 ...

  8. mongoDB数据库的简单使用

    我的第一篇小文章,以前总是写Evernote. mongodb属于非关系型数据库中的文档型数据库. 1.下载安装mongoDB, 文件自动 存放在这个目录下:C:\Program Files\Mong ...

  9. 隐马尔科夫模型HMM(一)HMM模型

    隐马尔科夫模型HMM(一)HMM模型基础 隐马尔科夫模型HMM(二)前向后向算法评估观察序列概率 隐马尔科夫模型HMM(三)鲍姆-韦尔奇算法求解HMM参数(TODO) 隐马尔科夫模型HMM(四)维特比 ...

  10. 安装Mysql5.7并修改初始密码

    Centos 安装MySQL可以参考之前写的一篇文章 Centos7.3 安装Mysql5.7并修改初始密码 windows安装mysql5.7有两种方式 1.下载.msi安装文件直接根据界面提示进行 ...