Unicode编码详解(三):UTF-8编码


本文为原创文章,转载请注明出处,或注明转载自“黄邦勇帅(原名:黄勇)

本文是对《C++语法详解》一书相关章节的增补,以增强读者对字符的理解,因为《C++语法详解》引用的标准过于老旧。

《C++语法详解》网盘地址:
https://pan.baidu.com/s/1dIxLMN5b91zpJN2sZv1MNg

本文摘自本人所作《Unicode编码和双向算法(bidi)详解》网盘地址
链接:https://pan.baidu.com/s/1LLKv22jQPmeba1XUCm0xoQ?pwd=a3x8
提取码:a3x8

有兴趣的读者可参阅本人所著《C++语法详解》一书,电子工业出版社出版,该书语法示例短小精悍,对查阅C++知识点相当方便,并对语法原理进行了透彻、深入详细的讲解,可确保读者彻底弄懂C++的原理,彻底解惑C++,使其知其然更知其所以然。此书是一本全面了解C++不可多得的案头必备图书。

由于本人能力有限,文中难免有错漏之处,望广大读者指出更正,不胜感激


注意:若对本文的专业术语不了解,请参阅本系列文章(一)和(二)

1、

UTF-8编码方式是目前使用最广泛的一种Unicode编码方式,但不是最早出现的,UTF-16比UTF-8早。

2、

UTF-8使用的是8位码元的变长码元序列编码方式,说简单点就是,使用变长字节来编码(即,编码后形成的二进制串长度不是固字的)。注意,UTF-8的码元长度是固定的8位,但编码后形成的码元序列长度不是固定的。UTF-8一般使用1到4个字节编码,当然也可以更长。

3、UTF-8编码方式的算法

首字节用于区分编码的字节数,即,从首字节就能判断出编码后有多少个字节。规则为:除单字节编码以0开头外,多字节编码首字节1的个数用于判断编码后的字节长度,然后紧接着以数字0作为终结标志,除首字节外,多字节编码的后续字节以10开头,具体规则如表5所示

4、UTF-8编码方法

①、在表5中查找字符的码点所在的码点范围,以确定应使用几个字节编码该字符
②、将字符的码点转换为二进制
③、将转换后的二进制数值从右到左(即从最后一位低位开始)依次按相同顺序填充表5中的x,多出的x填充0。
④、示例:“汉”的Unicode的码点是U+6C49 (110 1100 0100 1001 ) ,其编码过程如下:

  • 6C49在表5的码点范围为U+0800 ~ U+FFFF,所以应使用3个字节编码
  • 将6C49的二进制数110 1100 0100 1001从最后一位开始,按从右向左的顺序填充表5中的x,最终得到“汉”字的UTF-8编码为1110 0110 1011 0001 1000
    1001(0xE6 B189),如图2所示

5、UTF-8解码过程

①、当读到一个字节的首位为0时,表示这是一个单字节编码的字符(即,ASCII字符)
②、当读到一个字节的首位为1时,表示这是一个多字节编码的字符,分以下两种情形

  • 情形1:若继续读到1,则表示这是首字节,然后继续读到0为止,一共读取了几个1,就表示这个字符为几个字节的编码,
  • 情形2:若紧接着读到0,则表示该字节为多字节编码的后续字节。
6、UTF-8编码方式的显著特点

①、节省存储空间

  • 由于UTF-8使用的变长字节编码,所以,可以节省存储空间,比如,一个字节的ASCII字符,就可使用一个字节来存储,其他字符则可以使用多个字节来存储。

②、扩展性好

  • UTF-8的编码空间足够大(即,编码后的二进字串足够长),可适应Unicode标准更多的字符,因此,其扩展性好

③、与ASCII编码方式完全兼容

  • ASCII字符集中的字符(码点范围为U+0000~U+007F),用一个字节表示就可以了,其编码方式与ASCII编码一致,因此,UTF-8编码方式与ASCII编码方式完全兼容。但是,扩展ASCII字符集(比如EASCII字符集)中的扩展字符需要2个字节来编码

④、无字节序

  • UTF-8编码方式已经明确了字节的顺序,因此不存在字节序的问题

⑤、字节0xFE、0xFF与字节序标记(BOM)

  • 字节0xFE和0xFF永远不会在UTF-8编码中出现,因此,可使用这两个字节作为字节序标记(BOM)来标明UTF-16或UTF-32的字节序
  • 由于UTF-8编码不存在字节序的问题,因此没必要再添加BOM(即,字节序标记),若添加了BOM,则仅用于表明该文件是由UTF-8编码方式编码的,不再用于说明字节序。
  • 事实上,为使用UTF-8编码的文件加上BOM是多此一举的事情,但是,Windows还是加上了BOM(比如,记事本就有BOM),由此造成了很多不必要的麻烦,比如Unix系统就不建议使用BOM。
  • 注意:Windows为UTF-8加的BOM的值是0xEF BB BF,而UTF-16和UTF-32是直接以0xFEFF或0xFFFE来表示是大端序还是小端序的。为什么使用的是0xEF BB
    BF呢?这是因为0xEF BB BF是把0xFEFF按UTF-8编码后所得到的二进制串。所以,当遇到以0xEF BB BF开头的文件时,则表示这是以UTF-8的方式编码的文件

⑥、自同步和非传递性

  • 自同步:由于UTF-8编码仅通过检查一个码元便可判断出当前字符的下一个字符的起始码元,每个字符的边界很明确,因此在传输过程中若有字节序列丢失,并不会造成乱码现象,或者,当存在错误的字节序列时也不会影响到其他字节的正常读取,这一性质被称为“自同步”。比如,读取了一个10xxxxxx开始的字节,但找不到首字节,则可以直接丢弃后续字节,因为它没有意义。

  • 非传递性:是指单一的UTF-8码元出错不会被传递到文本的其他部分去,仅涉入到该字符,因此,文本中某些字符数据被破坏,其影响是局部的。

  • 若文本的编码不具有自同步和非传递性,则需从头开始分析文本才能确定不同字符的码元边界,同理,若局部字符数据被破坏,则很可能被传递到整个文本,从而导致整个文本都无法正确显示。很多早期其他的字符编码方式并不具有这两个特性,如GBK、Big等。

    ⑦、不利于索引操作、计算字符数等
    由于UTF-8是变长编码的,所以,不能根据字符数量直接判断出UTF-8文本的字节数(即,文本大小),因此,计算字符数、正则表达式检索等操作的效率都不高。

7、

UTF-8是较为理想的编码方式,因此应尽量使用UTF-8,特别应尽量使用UTF-8 without BOM(即,不带BOM的UTF-8)

本文作者:黄邦勇帅(原名:黄勇)

Unicode编码详解(三):UTF-8编码相关推荐

  1. 字符编码详解——彻底理解掌握编码知识,“乱码”不复存在

    每一个程序员都不可避免的遇到字符编码的问题,特别是做Web开发的程序员,"乱码问题"一直是让人头疼的问题,也许您已经很少遇到"乱码"问题,然而,对解决乱码的方法 ...

  2. java web编码详解_java web 开发 编码问题详解

    java web 开发 编码问题详解 浏览器 IE/FireFox ------------->Servlet容器-------------------------->显示页面 编码   ...

  3. Python2.7字符编码详解

    Python2.7字符编码详解 目录 Python2.7字符编码详解 声明 一. 字符编码基础 1.1 抽象字符清单(ACR) 1.2 已编码字符集(CCS) 1.3 字符编码格式(CEF) 1.3. ...

  4. 转1:Python字符编码详解

    Python27字符编码详解 声明 一 字符编码基础 1 抽象字符清单ACR 2 已编码字符集CCS 3 字符编码格式CEF 31 ASCII初创 311 ASCII 312 EASCII 32 MB ...

  5. 可能是最详细的字符编码详解

    Created By JishuBao on 2019-04-02 12:38:22 Recently revised in 2019-04-03 12:38:22   欢迎大家来到技术宝的掘金世界, ...

  6. 字符编码详解及由来(UNICODE,UTF-8,GBK)

    字符编码详解及由来(UNICODE,UTF-8,GBK) 各种字符编码方式详解及由来(ANSI,UNICODE,UTF-8,GB2312,GBK) - 2009-01-29 09:53     一直对 ...

  7. Unicode编码详解(二):编码预备知识

    Unicode编码详解(二):编码预备知识 本文为原创文章,转载请注明出处,或注明转载自"黄邦勇帅(原名:黄勇) 本文是对<C++语法详解>一书相关章节的增补,以增强读者对字符的 ...

  8. unicode编码详解_转载

    unicode编码详解,一看就懂  转载--https://www.cnblogs.com/hahlzj/p/11908713.html 一.Unicode编码 1 UTF-8 -16 -32编码和U ...

  9. 字符编码详解及利用C++ STL string遍历中文字符串

    作者:非妃是公主 专栏:<笔记><C++> 博客地址:https://blog.csdn.net/myf_666 个性签:顺境不惰,逆境不馁,以心制境,万事可成.--曾国藩 文 ...

最新文章

  1. 有效快速的学习微信小程序
  2. v深入研究Clang(四) Clang编译器的简单分析
  3. 记录一下PyQt5界面导入Python(绕开pyqt5-tools安装失败问题)
  4. python【蓝桥杯vip练习题库】ADV-97十进制数转八进制数
  5. Spring-AOP @AspectJ进阶之命名切点
  6. 沉浸式全息本是什么_“全息投影”走进健身房,打造沉浸式健身体验室,想来试试吗?...
  7. 实例36:python
  8. 显示天气 php代码,天气预报查询示例代码
  9. 【java】 获取计算机信息及Java信息
  10. 为何有 60% 的程序员拒绝公开讨论薪资?
  11. 一套代码在不同的电脑执行快慢_设计师需要的电脑配置
  12. MYSQL file types redo log
  13. C#自学总结_Day2
  14. Java获取一个月每周星期一至星期日的日期
  15. 聚合支付系统设计(三)
  16. 从softmax到ArcFace
  17. OSChina 周六乱弹 ——因为四毛钱,友谊的小船就翻了
  18. 蛋白质二级结构预测工具psipred安装使用
  19. python触屏模块_触摸屏滚动Tkinter Python
  20. 全国计算机考试有代码提示吗,全国计算机等级考试它又来啦~快来获取报名攻略!...

热门文章

  1. win11系统中安装CCS6图标太小的解决方法
  2. 在线安装Oculus rift驱动方法-20180706
  3. BPMN 2.0规范详解
  4. update过程中遇到kb2829760补丁无法更新而导致vs安装失败的解决方法: 1、安装KB2829760; 2、安装KB2829760中文语言包; 3、安装VS2013 with upda
  5. AI for everyone,阿里淘系MNN工作台正式公测!
  6. Eureka集群配置
  7. 如今流行的wifi营销,你了解多少?
  8. 概率论与数理统计(2)--均匀分布函数及其期望、方差
  9. 阿里云ClickHouse海量数据分析分享
  10. Windows修改C盘下的用户(Users)文件夹下的汉字文件夹