刨根究底字符编码之十——Unicode字符集的编码方式以及码点、码元
Unicode字符集的编码方式以及码点、码元
一、字符编码方式CEF的选择
1.
由于Unicode字符集非常大,有些字符的编号(码点值)需要两个或两个以上字节来表示,而要对这样的编号进行编码,也必须使用两个或两个以上字节。
比如,汉字“严”的Unicode码(Unicode码点值、Unicode编号)是十六进制数4E25,转换成二进制数有15位(100 1110 0010 0101),对“严”这个字符的编号进行编码的话,至少需要2个字节。表示其他更大编号的字符,可能需要3个字节或者4个字节,甚至更多。
2.
这带来两个问题:
一是,如何才能区别Unicode字符和ASCII字符的编码?计算机怎么知道三个字节表示的是一个字符,而不是分别表示三个字符呢?
二是,我们知道,英文字母只用一个字节来编码就够了,而如果Unicode统一硬性规定,每个字符都用两个、三个或四个字节来编码,那么每个英文字母编码的前面都必然有一个、两个到三个字节全是0,这对于存储和传输来说是极大的浪费。
这就涉及到了字符编码方式CEF的选择问题。Unicode字符的编码方式一般有三种:UFF-8、UTF-16、UTF-32。在具体介绍这些编码方式之前,需要再次深入了解两个概念——码点(Code Point)与码元(Code Unit)。
二、码点
1.
一个字符集一般可以用一张或多张由多个行和多个列所构成的二维表来表示。
二维表中行与列相交的点,称之为码点(Code Point代码点),也称之为码位(Code position代码位);每个码点分配一个唯一的编号,称之为码点值或码点编号,除开某些特殊区域(比如代理区、专用区)的非字符码点和保留码点,每个码点唯一对应于一个字符。
因此,除开非字符码点和保留码点,码点值(即码点编号)通常来说就是其所对应的字符的编号,所以码点值有时也可以直接称之为字符编号,虽然不够准确,但更为直接。
2.
字符集中所有码点数量的总和,称之为编号空间(Code Space,又被称之为代码空间、编码空间、码点空间、码空间)。
码点值最初用两个字节的十六进制数字表示,比如字母A的Unicode码点值为0041,常写作U+0041,这种形式称为Unicode码点名称,不严格地来讲,也可称之Unicode字符名称(因为存在着非字符码点和保留码点,并非每个码点都分配了字符,所以这种称呼不够准确,不过目前更为普遍)。
3.
后来随着Unicode字符集的不断增补扩大(比如现在的Unicode字符集至少需要21位才能全部表示),码点值也扩展为用三个字节或以上的十六进制数字表示。
例如,ASCII字符集用0~127这连续的128个数字编号分别表示128个字符。GBK字符集使用区位码的方式为每个字符编号,首先定义一个94×94的矩阵,行称为“区”,列称为“位”,然后将所有国标汉字放入矩阵当中,这样每个汉字就可以用唯一的“区位”码来标识了。例如“中”字被放到54区第48位,因此其区位码(字符编号)就是5448。
而目前Unicode标准中,将字符按照一定的类别划分到0~16这17个平面(Plane层面)中,每个平面中拥有2^16 = 65536个码点,因此,目前Unicode字符集所拥有的码点总数,也就是Unicode的编号空间为17*65536=1114112。
注意,网络上的很多文章中,代码点、码点、码点值、码值、代码位、码位、字符码、Unicode码、字符编号、字符编码、编码方案、编码方式、编码格式等等经常互相代替混用。
(笨笨阿林原创文章,转载请注明出处)
三、码元
1.
在计算机存储和网络传输时,码点值(即字符编号)被映射到一个或多个码元(Code Unit代码单元、编码单元)。
码元可理解为字符编码方式CEF(Character Encoding Form)对码点值进行编码处理时作为一个整体来看待的最小基本单元(基本单位)。
2.
为什么非要引入“码元”这个概念?或者说,为什么非要强调“码元”这个概念?
码元某种程度上可认为对应于高级语言中的基本数据类型。而高级语言层面的基本数据类型,若要更深入一步地来讲,实质上对应于机器硬件层面(汇编语言)的数据类型byte字节、word字、dword双字等在硬件中的表达与处理机制。
之所以要强调“码元”的概念,是因为字符编码作为一串数字序列,最终还是得通过机器硬件层面的数据类型来表示。
而码元的实质,就是机器硬件层面(汇编语言)的数据类型;不同的码元,代表着不同位数的数据类型。
3.
数据类型有单字节与多字节之分,所以码元也有单字节与多字节之分;多字节数据类型由于历史的原因,存在着字节序的所谓大端序(Big-Endian)与小端序(Little-Endian)之分,因此多字节码元也存在着大端序与小端序之分(具体详见前文中有关字节序的解释;注意,单字节数据类型则没有字节序的问题,所以单字节码元也就没有字节序问题)。
这就是之所以要强调“码元”这个概念的关键原因。
4.
码点值(即字符编号)的具体实现方式——字符编码方式CEF,就是由一个或多个码元这样的最小基本单元构成的。
最常用的码元是8位(1字节)的单字节码元,另外还有16位(2字节)和32位(4字节)两种多字节码元,分别相当于C++中的无符号整型BYTE、WORD、DWORD(在VC++6.0中,这三种数据类型的定义分别为:
typedef unsigned char BYTE;,1个字节;
typedef unsigned short WORD;,2个字节;
typedef unsigned long DWORD;,4个字节)。
(笨笨阿林原创文章,转载请注明出处)
5.
于是,三种码元对应就有了Unicode字符编号(码点值)的三种UTF编码方式(即Unicode码转换格式Unicode Transformation Format,或称通用字符集转换格式UCS Transformation Format):
UTF-8(8-bit Unicode/UCS Transformation Format),
UTF-16(16-bit Unicode/UCS Transformation Format),
UTF-32(32-bit Unicode/UCS Transformation Format);
或者反过来说,Unicode字符编号(码点值)的三种UTF编码方式(UTF-8、UTF-16、UTF-32)分别采用了不同的码元(BYTE、WORD、DWORD)来编码。
例如,“汉字”这两个中文字符的Unicode码点值(Unicode字符编号)是0x6C49和0x5B57,其三种UTF编码在VC++6.0中可按如下定义进行“模拟”:
6.
注意,这里之所以说是“模拟”,因为从本质上来讲,在机器硬件层面上的所有数据类型,只存在着被视作一个整体来处理的比特序列(比特流)的位数不同之分,不存在着高级语言层面上数据类型的数值、字符串、布尔值等的语义不同之分。
因此,机器硬件层面上的数据类型与高级语言层面上的数据类型,严格来讲,在本质含义上还是有着很大不同的。当然,高级语言层面上的数据类型最终还是会被转化为机器硬件层面上的数据类型,毕竟计算机只“认识”由0和1所组成的比特流。具体详见前文中有关字节序的解释。
7.
这里用BYTE、WORD、DWORD分别表示无符号8位整数、无符号16位整数和无符号32位整数;因而UTF-8、UTF-16、UTF-32可认为分别以BYTE、WORD、DWORD作为码元。
“汉字”这两个中文字符的UTF-8编码需要六个BYTE(共6个单字节码元),大小是6个字节;UTF-16编码需要两个WORD(共2个双字节码元),大小是4个字节;UTF-32编码需要两个DWORD(共2个四字节码元),大小是8个字节。
由于多字节数据类型的数据在计算机存取时存在一个字节序的问题,因此,UTF-16、UTF-32这两种编码方式所编码出来的逻辑意义上的多字节码元序列,在映射为物理意义上的字节序列时,字节序列的字节序因系统平台的不同而不同。
前面已经多次强调过了,这里再次特别强调一下:由单字节数据类型所组成的多字节数据是不存在字节序的问题的。因此,采用单字节码元进行编码的UTF-8编码,虽然ASCII字符为单字节编码,但非ASCII字符是多字节编码的,但却不存在字节序问题,这是跟同样为多字节编码、但采用多字节码元的UTF-16、UTF-32不同之处。详见下表所列:
Unicode字符集三大编码方式(UTF-8、UTF-16、UTF-32)比较一览表
(笨笨阿林原创文章,转载请注明出处)
【预告:下一篇将重点讲解UTF-8编码方式与字节序标记(BOM),敬请关注!】
<div id="blog_post_info">
关注 - 5
粉丝 - 66
« 上一篇: 刨根究底字符编码之九——字符编码方案的演变与字节序
» 下一篇: 刨根究底正则表达式之零——前言
刨根究底字符编码之十——Unicode字符集的编码方式以及码点、码元相关推荐
- 【转】刨根究底字符编码之十——Unicode字符集的字符编码方式
一.字符编码方式CEF的选择 1. 由于Unicode字符集非常大(并且作为开放字符集还在不断扩展之中),有些字符的编号(即码点值)需要两个或两个以上字节来表示,而要对这样的编号进行编码,也必须使用两 ...
- ORACLE HANDBOOK系列之十:字符集、编码以及Oracle的那些事
第一部分字符集与编码常识 字符集: 人们根据需要把某些字符收集到一处,并赋以名称,于是便有了某某字符集. 编码: 当前面收集的工作完成以后,为了让只认识数字的"愚蠢"的计算机也能够 ...
- unicode字符集与编码
字符编码 个人理解 一个字符需要保存到计算机中,计算机只能识别0.1.这就需要一个规则来表述0.1数据与字符之间的关系. ASCII码 表述 1个字节 0.1数据与字符之间的关系. 非ASCII码 英 ...
- 【字符编码详解】ASCII、GB2312、GBK、UTF-8、UTF-16编码与Unicode字符集
目录 前言 一.什么是编码,数据类型和编码有什么关系? 二.英文字符编码 ASCII编码 三.中文编码 1. GB2312标准 2. GBK编码 3. 其他中文编码 四.Unicode字符集 1. U ...
- 【转】刨根究底字符编码之零——前言
前言 一. 字符编码是计算机世界里最基础.最重要的一个主题之一.不过,在计算机教材中却往往浮光掠影般地草草带过,甚至连一本专门进行深入介绍的著作都找不到(对这一点我一直很困惑,为什么就没有哪位大牛对这 ...
- 【转】刨根究底字符编码【2.0版】(1):开篇
首先跟大家分享一个有趣的亲身经历.有一次,在网上我看到有程序员发了一个帖子,帖子题目乍一看让人感到惊愕,但细一想又让我会心一笑. 这个帖子的题目大致上是这样的:字符编码是不是让程序员最感到恶心的问题? ...
- 【转】刨根究底字符编码之十三——UTF-16编码方式
1. UTF-16编码方式源于UCS-2(Universal Character Set coded in 2 octets.2-byte Universal Character Set).而UCS- ...
- 刨根问底:C++中宽字符类型(wchar_t)的编码一定是Unicode?长度一定是16位?
转发的:https://www.ituring.com.cn/article/111027的文章 刨根问底:C++中宽字符类型(wchar_t)的编码一定是Unicode?长度一定是16位? cons ...
- 【转】刨根究底字符编码之七——ANSI编码与代码页
一.ANSI编码 1. 如前所述,在全世界所有国家和地区的文字符号统一编码的UCS/Unicode编码方案问世之前(UCS.Unicode后文有详细介绍),各个国家.地区为了用计算机记录并显示自己的字 ...
- 【转】刨根究底字符编码之二——关键术语解释(下)
关键术语解释(下) 如前所述,现代字符编码模型共分为5层,下面分层进行简要介绍. 一.第1层 抽象字符表ACR (Abstract Character Repertoire抽象字符清单):明确字符的范 ...
最新文章
- 用数据告诉你王思聪到底有多少钱?
- hashmap是散列表吗_一篇文章教你读懂哈希表-HashMap
- W3School-CSS 表格实例
- 无法加载主类的10中方法
- 前端必须掌握的经典布局:“双飞翼布局”
- html5硬件接口,HTML5通用接口详解
- 国家机构测评主流电视品牌语音识别 长虹Q5K综合评价最佳
- 在老MAC系统上编译OpenJDK8,顺利通过
- 如何快速把英语单词导入有道词典
- Mac配置allure环境变量
- 黑马程序员_JavaWeb013
- 梦幻西游脚本开发教学
- 开发规约:接口统一返回值格式 [resend]
- su联合推拉使用方法_紫天学习星球教学:联合推拉插件完全功能使用详解(中文)...
- [电脑桌面右击新建没有excel、ppt、word]
- RGB 转换为灰度图、二值化图
- 你所不知道的精神分裂症
- Jsp新闻项目(规范访问分页之模糊查询主题分页查询[客户页面])
- 养鸡场的计算机管理,养鸡场管理系统7.3 免费版
- 2014暑假(第八届)全国高校物联网专业师资培训通知
热门文章
- 4、BFS算法套路框架——Go语言版
- JSON 对比工具,优秀的JSON对比工具,文件内容对比
- java JSPX的介绍(转载)
- Openrefine mysql_openrefine 2.5稳定版-OpenRefine下载(数据清洗工具) 2.5 官方稳定版 - 河东下载站...
- 典型相关分析(CCA)
- SnakeYaml 反序列化的一个小 trick
- 物联网安全专题 | 浅谈物联网设备安全分析方法 — 硬件篇
- matlab光滑曲线链接,在Matlab中使用光滑曲线连接点
- RetinaFace+ArcFace人脸识别测试
- DEDECMS5.7自动采集更新伪原创插件高级版GBK