【转】刨根究底字符编码之二——关键术语解释(下)

关键术语解释(下)

如前所述,现代字符编码模型共分为5层,下面分层进行简要介绍。

一、第1层 抽象字符表ACR (Abstract Character Repertoire抽象字符清单):明确字符的范围(即确定支持哪些字符)

1.

抽象字符表ACR是一个编码系统支持的所有抽象字符的集合,可以简单理解为无序的字符集合,用于确定字符的范围,即要支持哪些字符。

抽象字符表ACR的一个重要特点是字符的无序性,即其中的字符并没有编排数字顺序,当然也就没有数字编号。

2.

抽象”字符不具有某种特定的字形,不应与具有某种特定字形的“具体”字符混淆。

3.

字符表可以是封闭的(即字符范围是固定的),即除非创建一个新的标准,否则不允许添加新的字符,比如ASCII字符表和ISO/IEC 8859系列都是这样的例子;字符表也可以是开放的(即字符范围是不固定的),即允许不断添加新的字符,比如Unicode字符表和一定程度上Code Page代码页(代码页后文会有详细解释)是这方面的例子。

二、第2层 编号字符集CCS(Coded Character Set):用数字编号表示字符(即用数字给字符编号)

注:一般将“Coded Character Set”翻译为“编码字符集”或“已编码字符集”,但这里的“编码”二字容易导致与后文的“编码方式”及“编码模式”中的“编码”二字混淆,带来理解上的困扰,因此觉得翻译为“编号字符集”为宜。

1.

前面讲了,抽象字符表里的字符是没有编排顺序的,但无序的抽象字符表只能判断某个字符是否属于某个字符表,却无法方便地引用、指称该字符表中的某个特定字符。

为了更方便地引用、指称字符表中的字符,就必须为抽象字符表中的每个字符进行编号。

所谓字符编号,就是将抽象字符表ACR中的每个抽象字符(简称字符)表示为1个非负整数N或者映射到1个坐标(非负整数值对x, y),也就是将抽象字符的集合映射到一个非负整数或非负整数值对的集合,映射的结果就是编号字符集CCS。因此,字符的编号也就是字符的非负整数代码。

例如,在一个给定的抽象字符表中,表示大写拉丁字母“A”的字符被赋予非负整数65、字符“B”是66,如此继续下去。

2.

由此产生了编号空间(Code Space,一般翻译为代码空间、码空间、码点空间)的概念:根据抽象字符表中抽象字符的数目,可以设定一个字符编号的上限值(该上限值往往设定为大于抽象字符表中的字符总数),从0到该上限值之间的非负整数范围就称之为编号空间。

编号空间的描述:

1)可以用一对非负整数来描述,例如:GB2312的汉字编号空间是94 x 94;

2)也可以用一个非负整数来描述,例如:ISO-8859-1的编号空间是256;

3)也可以用字符的存储单元尺寸来描述,例如:ISO-8859-1是一个8比特的编号空间(2^8=256);

4)还可以用其子集来描述,如行、列、面(Plane平面、层面)等等。

3.

编号空间中的一个位置(Position)称为码点(Code Point代码点)码位(Code Position代码位)。一个字符占用的码点所在的坐标(非负整数值对)或所代表的非负整数,就是该字符的编号,又称之为码点值(即码点编号)

不过,严格来讲,字符编号并不完全等同于码点编号(即码点值)。因为事实上,由于某些特殊的原因,编号字符集CCS里的码点数量要大于抽象字符表ACR中的字符数量。

在编号字符集中,除了字符码点之外,还存在着非字符码点和保留码点,所以字符编号不如码点编号准确;但若对字符码点的码点编号称之为字符编号,倒也更为直接。

在Unicode编码方案中,字符码点又称之为Unicode标量值(Unicode Scalar Value,感觉不如字符码点更为直观),非字符码点和保留码点详见后文介绍。

4.

注意,经常直接以“码点”指代“码点值”——当说到“码点”的时候,有可能是在说编号空间(即码点空间)中的一个位置,即码点;也有可能实际是在说某个码点的码点值,即码点编号。其具体含义需根据上下文而定。

这种类似的指代非常普遍,又比如“字符集”、“字符编号”和“字符编码”这三个概念就经常相互指代。以“码点”指代“码点值”,根据上下文,倒也还不难理解;但“字符集”、“字符编号”和“字符编码”三者也经常相互指代,虽然有其令人无奈的历史原因,但目前的实际情况所导致的结果却是使人迷惑、让人抓狂!

5.

因此,所谓编号字符集,可简单理解为就是把抽象字符进行逐个编号或者说逐个映射为码点值(即码点编号)后所得到的结果。

编号字符集CCS常简称为字符集。

注意不要将编号字符集CCS和抽象字符表ACR相混淆。多个不同的编号字符集CCS可以表示同一个抽象字符表ACR;换言之,同一个抽象字符表ACR,可以按不同的编号规则被编号为多个不同的编号字符集CCS。

6.

在Unicode标准中,一个单个的抽象字符,既有可能与多个码点对应(为了与其它标准兼容,比如码点编号为U+51C9与U+F979的这两个码点实际上是同一个字符“凉”,这是为了兼容韩国字符集标准KS X 1001:1998,具体可参看Unicode的官方文档),也有可能使用一个由多个码点所组成的码点序列表示(为了表示由基本字符与组合字符组合在一起所组成的字符,比如à,由码点编号为U+0061的基本字符字母“a”和码点编号为U+0300的组合字符读音符号“̀”组成);同时,也并非每一个码点都对应于一个字符,也存在着非字符码点或保留码点。详见后文解释。

7.

特别注意:虽然“编号”与后文某种字符编码方式CEF中的“编码”(即码元序列,解释详见后文)以及某种字符编码模式CES中的“编码”(即字节序列,解释详见后文)存在着对应的关系,但“编号”与“编码”是截然不同的两个概念

对字符编号的过程——即确定字符码点值的过程,跟计算机还没有直接关系,可认为是一个纯数学的问题,因为只是将字符与编号(即码点值、码点编号)一一对应起来,根本就还没有涉及到编码算法的问题(即还没有涉及到:根据指定的字符编码方式CEF对编号进行编码以形成码元序列,以及根据指定的字符编码模式CES对码元序列进一步编码以形成字节序列)。

但这两个概念经常被混用,实实在在是让人困惑的源头,这是很令人无奈与遗憾的现实。

三、第3层 字符编码方式CEF(Character Encoding Form字符编码形式、字符编码格式、字符编码规则):将字符编号(即码点值)编码为码元序列(即字符编码)

1.

在讲抽象字符表ACR时说过,不同于传统的封闭的ASCII字符表其字符数是固定的,Unicode字符表是一个现代的开放的字符表,其字符数是不固定的,未来可能有更多的字符加入进来(比如很多Emoji表情符就被源源不断地加入进来)。因此,Unicode编号字符集所需要的码点数量,必然是会不断增加的,相对来说是无限的。

但计算机所能表示的整数范围却是相对有限的。比如,一个无符号单字节整型数(unsigned char, uint8)能够表示的编号只有0~0xFF,共256个;一个无符号双字节短整型数(unsigned short, uint16)能够表示的编号只有0~0xFFFF,共65536个;而一个无符号四字节长整型数(unsigned long, uint32)能表示的编号只有0~0xFFFFFFFF,共4294967296个。

2.

那么问题来了:

1)一方面,怎么通过相对有限的整型数来高可扩展地、高可适应地应对未来相对无限增长的字符数量呢?是用多个单字节整型数来间接表示,还是用一个足够大的多字节整型数来直接表示呢?

2)另一方面,ASCII字符编码作为最早出现、已被广泛应用的编码方案,完全不兼容显然不明智,那么是直接兼容,还是间接兼容呢?

这两方面的问题需要一个综合解决方案,这就是字符编码方式CEF(Character Encoding Form)

3.

字符编码方式CEF,是将编号字符集里字符的码点值(即码点编号、字符编号)转换成或者说编码成有限比特长度的编码值(即字符编码)。该编码值实际上是码元(Code Unit代码单元、编码单元)的序列(Code Unit Sequence)

那什么是码元呢?为什么要引入码元这个概念呢?字符集里的字符编号(即码点值、码点编号)又是如何转换为计算机中的字符编码(即码元序列)的呢?别急,这里先记下这个概念,暂不深究,后文有详细解释。

4.

字符编码方式CEF也被称为“存储格式”(Storage Format)。不过,将CEF称之为存储格式实际上并不合理,因为CEF还只是逻辑层面上的、与特定的计算机系统平台无关的编码方式,尚未涉及到物理层面上的、与特定的计算机系统平台相关的存储方式(第4层才涉及到)。

在ASCII这样传统的、简单的字符编码系统中,并没有也不需要区分字符编号与字符编码,可认为字符编号就是字符编码,字符编号与字符编码之间是一个直接映射的关系。

而在Unicode这样现代的、复杂的字符编码系统中,则必须区分字符编号与字符编码,字符编号不一定等于字符编码,字符编号与字符编码之间不一定是一个直接映射的关系,比如UTF-8、UTF-16为间接映射,而UTF-32则为直接映射。

UTF-8、UTF-16与UTF-32等就是Unicode字符集(即编号字符集)常用的字符编码方式CEF。(UTF-8、UTF-16与UTF-32后文各有详细介绍)

5.

很多文章中,将Unicode与各UTF(Unicode/UCS Transformation Format,包括UTF-8、UTF-16与UTF-32等)之间的关系表述为:Unicode为标准规范、各UTF为编码实现。

不严格地来讲,也可以勉强这么认为。不过,这种表述毕竟不够严谨,而且无助于理解Unicode标准(即Unicode编码方案、Unicode编码系统)、Unicode字符集与各UTF字符编码方式这三者之间更为深入细致的关系。

注:现代字符编码模型的角度来看,Unicode编码标准Unicode编码方案Unicode编码系统基本上为同义词,是包括了抽象字符表ACR编号字符集CCS字符编码方式CEF以及下面要讲到的字符编码模式CES甚至传输编码语法TES五个层面在内的一整套标准方案系统,并不特指其中的某一层。

四、第4层 字符编码模式CES(Character Encoding Scheme):将码元序列映射为字节序列

注:一般将“Character Encoding Scheme”翻译为“字符编码方案”,但习惯上通常将“字符编码标准”或“字符编码系统”称之为“字符编码方案”,为避免引起理解上的困扰,应译作“字符编码模式”为宜。

1.

字符编码模式CES,也称作“序列化格式”(Serialization Format),指的是将字符编号进行编码之后的码元序列映射为字节序列(即字节流)后的形式,以便经过编码后的字符能在计算机中进行处理、存储和传输。

如果说将编号字符集的码点值(即字符编号)映射为(即编码为)码元序列的过程属于跟特定的计算机系统平台无关的逻辑意义上的编码过程(该编码过程即第3层的字符编码方式CEF的编码过程),那么将码元序列映射为字节序列的过程就属于跟特定的计算机系统平台相关的物理意义上的编码过程(该编码过程即第4层的字符编码模式CES的编码过程)。

2.

由于硬件平台与操作系统设计上的历史原因,对于UTF-16、UTF-32等采用多字节码元的编码方式而言,必须使用一个原先称之为零宽度不中断空格(ZERO WIDTH NO-BREAK SPACE)的字符(Unicode字符编号为0xFEFF)来指定字节序(Byte-Order字节顺序、位元组顺序,或称为Endianness端序)是大端序还是小端序,计算机才能够正确地进行处理、存储和传输。(什么是字节序以及大端序、小端序,解释详见后文)

不过,对于UTF-8这种采用单字节码元的编码方式来说,并不存在字节序问题,不需要指明字节序。因此,在各种计算机系统平台中,UTF-8编码的码元序列与字节序列都是相同的。(为什么UTF-8不存在字节序问题,解释详见后文)

3.

注意,由于字符编码方式CEF字符编码模式CES中都有“编码”二字,因此,通常所说的动词编码(Encode)有可能指的是通过字符编码方式CEF将编号字符集CCS的字符编号转变码元序列;也有可能指的是通过字符编码模式CES将字符编码方式CEF的码元序列转变字节序列

动词解码(Decode)则反过来,当然也同样存在两种可能。

而通常所说的名词编码(Encoding)也就相应地有可能指的是码元序列,也有可能指的是字节序列。(当然,在很多文章中,名词编码往往实际上表述的是字符的编号,既非码元序列,亦非字节序列,虽然有其历史原因,但从现代字符编码模型的角度来看,这应算作是一种错误表述,或至少可认为是表述不够严谨。)

因此,必须根据上下文语境来具体理解。

4.

对于程序员而言,通过字符编码方式CEF编码后所形成的码元序列,更多的是一种逻辑意义上的中间编码(即编码中介,属于从字符编号到字节序列的中间状态,作为将字符编号转换为字节序列的中介而存在),不是平时直接“打交道”的对象。

而通过字符编码模式CES将码元序列进一步编码后所形成的字节序列,才是平时直接“打交道”最多的物理意义上的最终编码(虽然事实上还有第5层的传输编码语法TES所形成的编码,但这种编码毕竟仅用于某些特殊的传输环境,平时“打交道”的机会较少)。

五、第5层 传输编码语法TES(Ttransfer Encoding Syntax):将字节序列作进一步的适应性编码处理

由于历史的原因,在某些特殊的传输环境中,需要对上一层次的字符编码模式CES所提供的字节序列(字节流)作进一步的适应性编码处理。一般包括两种:

1)一种是把字节序列映射到一套更受限制的值域内,以满足传输环境的限制,例如用于Email传输的Base64编码或者quoted-printable编码(可打印字符引用编码),都是把8位的字节映射为7位长的数据。

注:Email协议设计为仅能传输7位的ASCII字符;从一个8位字节的角度来看,ASCII字符的首位始终为0,所以除去首位的0,实际有效的位数为7位,或许最初是出于节约传输流量的考虑,Email协议被设计为了仅能传输7位的ASCII字符。

2)另一种是压缩字节序列的值,如LZW或者进程长度编码等无损压缩技术。

(这一部分内容本文不深入阐述,有兴趣者可自行查找资料。)

六、总结一下现代字符编码模型:

 

对于Unicode这样的现代字符编码系统来说,同一个字符因多个不同的字符编码方式CEF(如UTF-8、UTF-16、UTF-32等)而具有多个不同的码元序列(Code Unit Sequence),同一个码元序列因两个不同的字符编码模式CES(大端序模式、小端序模式)而又可能具有两个不同的字节序列(Byte Sequence)

但这些不同的码元序列也好,字节序列也好,只要表示的是同一个字符,所对应的码点值(即码点编号、字符编号)一般都是相同的(在Unicode标准中,为了与其它标准兼容,有少数字符可能与多个码点对应)。

好了,关键术语先解释到这里,其他术语将在后文中陆续解释。

 

二次总结:(1)

1. 5 层模型:

五层:Transfer Encoding Syntax(传输编码语法)

(将字节序列做进一步适应性编码处理)

|

四层:Character Encoding Scheme (字符编码模式)

(将逻辑上的码元序列映射成物理上的字节序列)

|

三层:Character Encoding Form(字符编码格式)

(将字符编号编码为码元序列,即:字符编码)

|

二层:Coded Character Set(编号字符集)

(用数字给 ACR 中的字符编号)

|

一层:Abstract Character Repertoire (抽象字符表)

(明确字符的范围,即确定支持哪些字符)

 

二次总结:(2)

1. 二层(CCS 中):

Code Position(字符编号 / 码点值 / 字符码点)

一个字符占用的码点所在的坐标(非负整数值对)或所代表的非负整数,就是该字符的编号

 

2.第三层(CEF 中):

码元序列(字符编码)

字符编码方式CEF,将编号字符集里字符的码点值(即码点编号、字符编号)转换成或者说编码成有限比特长度的编码值(即字符编码)。该编码值实际上是码元(Code Unit代码单元、编码单元)的序列(Code Unit Sequence)。

 

UTF-8 / UTF-16 / UTF-32

就是 Unicode 字符集(即编号字符集)常用的字符编码方式CEF。

 

 

3. 第四层(CES 中):

字节序列 (同时解释了字节序列)

也称作“序列化格式”(Serialization Format),是将字符编号进行编码之后的码元序列映射为字节序列(即字节流),以便编码后的字符在计算机中进行处理、存储和传输。

 

 

 

 

5. 关于 Unicode 和 UTF-8 / UTF-16 / UTF-32 的理解

Unicode标准、Unicode编码方案、Unicode编码系统基本上为同义词,是包括了抽象字符表ACR、编号字符集CCS、字符编码方式CEF以、字符编码模式CES、传输编码语法TES在内的一整套标准方案系统,并不特指某一个层面。而 UTF-8 / UTF-16 / UTF-32 仅仅指 CEF (字符编码方式)。

 

 

 

 

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/437491.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【转】刨根究底字符编码之三——字符编码的由来

字符编码的由来 一、为什么需要对字符进行编码 1. 计算机一开始发明出来时是用来解决数字计算问题的,后来人们发现,计算机还可以做更多的事,例如文本处理。 但计算机其实挺“笨”的,它只“认识”010110111000…这样由0和1两个数…

SpringMVC配置没问题却却找不到页面,页面显示404

在Artifacts下此工程下新建一个lib文件夹,存放jar包,因为idea新建modules的时候不是直接创建的web项目: 选中lib点加号把jar导入进去,然后重启tomcat

【转】刨根究底字符编码之四——EASCII及ISO 8859字符编码方案

1. 计算机出现之后,首先逐渐从美国发展到了欧洲。由于欧洲很多国家所用到的字符中,除了基本的、美国也用的那128个ASCII字符之外,还有很多衍生的拉丁字母等字符。比如,在法语中,字母上方有注音符号;而欧洲…

tomcat乱码问题解决

tomcat安装目录下conf文件夹下的logging.properties文件,将java.util.logging.ConsoleHandler.encoding编码为GBK,如图:

【转】HMAC哈希消息认证码及算法原理

HMAC算法原理 HMAC算法是一种基于密钥的报文完整性的验证方法 ,其安全性是建立在Hash加密算法基础上的。它要求通信双方共享密钥、约定算法、对报文进行Hash运算,形成固定长度的认证码。通信双方通过认证码的校验来确定报文的合法性。 HMAC算法可以用来…

RestFul风格学习

传统的url是这样的 RestFul是这样的

Angular使用Console.log()打印出来的数据没问题,点击详情后数据变了

我在一个界面添加数据使用updataEvent将对象返回给另一个界面后,在onUpData中处理时使用 this.xxxxx d,直接将地址值给了变量,当这个方法结束后d被重置了,所以this.xxx的值也消失了,这里要使用下面的方法复制一个对象出来。 this…

【转】刨根究底CSS(1):开篇

01 一道小菜 CSS很难,这应该是绝大多数Web开发人员的共识。 什么?你并不觉得很难?那我就先上一道小菜,请君品尝。 这是个乍一看,让人觉得很诡异的案例…… 算了,本来想滔滔不绝介绍一番,但一…

【转】刨根究底CSS(2):CSS中的各种值——初始值,就是默认值吗?

先问个非常简单的问题,这个问题的答案,相信大部分Web开发人员都自认为显而易见,但却又多半会答错:CSS属性中的初始值(initial value),就是默认值(default value)吗? 难道不对吗?请往下看。 默…

台式机电脑配置单_2020年电脑配置单重点硬件参考

,电脑的基本配件扫盲我前面写过很多,相信很多小伙伴都看过了,没有看过的可以上我专栏参观:电脑神棍局-组装机专栏​www.zhihu.com配置单在本文后面两篇,但是建议前面花两分钟看下。游戏篇后续还有工作和视频工作站篇主…

【转】刨根究底字符编码之五——简体汉字编码方案(GB2312、GBK等)以及全角、半角、CJK

一、概述 1. 英文字母再加一些其他标点字符之类的也不会超过256个,用一个字节来表示一个字符就足够了(2^8 256)。但其他一些文字不止这么多字符,比如中文中的汉字就多达10多万个,一个字节只能表示256个字符,肯定是不够的&#…

开机cpu风扇声音大_联想拯救者R720笔记本,开机显示暗屏,二修机多故障完美修复...

【机器型号】拯救者R720-15(7代I5)【主板版号】NM-B191【故障现象】笔记本不开机接同行送修笔记本拯救者R720-15,7代I5的机器,同行描述说不开机。【维修过程】 拿到机器按下开关没反映,三下五除二,扒下这台电脑的衣服,…

【转】刨根究底字符编码之六——简体汉字编码中区位码、国标码、机内码、外码、字形码的区别及关系

GB2312、GBK、GB18030等GB系列汉字编码方案的具体实现方式是怎样的?区位码是什么?国标码是什么?内码、外码、字形码又是什么意思?它们是如何转换的,又为什么要这样转换? 下面以GB2312为例来加以说明。 一、…

公共链接url出错_SEO优化技巧:关于URL的优化方法

点击标题下「蓝色微信名」可快速关注URL优化需要遵循一些原则, 采用以下方法,网页的用户体验更佳,同时对搜索引擎更友好。01URL越短越好对于搜索引擎来说,只要URL不超过265Byte,收录就没有问题。如果使用几百个字母的U…

【转】刨根究底字符编码之七——ANSI编码与代码页

一、ANSI编码 1. 如前所述,在全世界所有国家和地区的文字符号统一编码的UCS/Unicode编码方案问世之前(UCS、Unicode后文有详细介绍),各个国家、地区为了用计算机记录并显示自己的字符,都在ASCII编码方案的基础上,设计了各自的编…

Angular 下拉搜索框实现

今天有个需求要写一个下拉搜索框&#xff0c;本来是下拉框的&#xff0c;由于内容太多&#xff0c;所以添加一个查找功能。根据博客进行改写的。参考了他的基本框架进行实现。 效果图&#xff1a; 输入框右边的白色箭头图片下载地址 <td>xxxxxxx</td> <td sty…

新手前端练手网站_编程到底难不难学?新手入门选择哪种语言好?

以下内容适合的读者&#xff1a;想要学习编程的小白一.编程到底难不难学&#xff1f;对于这个问题我的回答是不知道&#xff0c;学会了编程的人会说好学&#xff0c;中途就放弃的人会说很难&#xff0c;任何知识想要掌握好都不是一件容易的事情。所以我决定用自己的实际行动来证…

【转】刨根究底字符编码之八——Unicode编码方案概述

Unicode编码方案概述 1. 前面讲过&#xff0c;随着计算机发展到世界各地&#xff0c;于是各个国家和地区各自为政&#xff0c;搞出了很多既兼容ASCII但互相之间又不兼容的各种编码方案(微软统一称之为ANSI编码&#xff0c;具体体现为各种ANSI代码页)。 这样一来&#xff0c;同…

Angular 自定义属性指令-禁止input框输入空格-以及删除复制内容中的空格

创建一个ts文件&#xff0c;并在module.ts中定义 import { Directive, ElementRef, HostListener, Input } from angular/core; import { FormGroup, FormControl, NgControl } from angular/forms; Directive({selector: [input-noSpace]}) export class NoSpace {constructo…

基于androidx的快速开发框架_Vue企业级优雅实战07框架开发03封装基于MockJS的模拟数据...

预览本文的实现效果&#xff1a;# giteegit clone gitgitee.com:cloudyly/dscloudy-admin-single.git# githubgit clone gitgithub.com:cloudyly/dscloudy-admin-single.gitgit checkout 05_MockJS本文主要内容&#xff1a;基于 Mock JS&#xff0c;优雅设计网络请求的模拟数据…