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

UTF-8究竟是怎么编码的

1.

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

为什么要变长呢?这可以理解为按需分配,比如一个字节足以容纳所有的ASCII字符,那何必补一堆0,导致占用更多的字节来存储呢?

实际上变长编码有其优势,也有其劣势,优势方面除了上面所讲的节省存储空间之外,还有就是自动纠错性能好、利于传输、扩展性强,而劣势方面主要是由于字符的编码字节数不固定导致不利于程序内部处理,比如导致正则表达式检索的复杂度大为增加;而UTF-32这样的等长码元序列(即等宽码元序列)的编码方式就比较适合程序处理,当然,缺点是比较耗费存储空间。

2.

那UTF-8究竟是怎么编码的呢?也就是说其编码算法是什么?

UTF-8编码最短的为一个字节、最长的目前为四个字节,从首字节就可以判断一个UTF-8编码有几个字节:

  • 如果首字节以0开头,肯定是单字节编码(即单个单字节码元);
  • 如果首字节以110开头,肯定是双字节编码(即由两个单字节码元所组成的双码元序列);
  • 如果首字节以1110开头,肯定是三字节编码(即由三个单字节码元所组成的三码元序列),以此类推。

另外,UTF-8编码中,除了单字节编码外,由多个单字节码元所组成的多字节编码其首字节以外的后续字节均以10开头(以区别于单字节编码以及多字节编码的首字节)。

0、110、1110以及10相当于UTF-8编码中各个字节的前缀,因此称之为前缀码。其中,前缀码110、1110及10中的0,是前缀码中的终结标志。

UTF-8编码中的前缀码起到了很好的区分和标识的作用:

  • 当解码程序读取到一个字节的首位为0,表示这是一个单字节编码的ASCII字符;
  • 当读取到一个字节的首位为1,表示这是一个非ASCII字符的多字节编码字符中的某个字节(可能是首字节,也可能是后续字节),接下来若继续读取到一个1,则确定为首字节,再继续读取直到遇见终结标志0为止,读取了几个1,就表示该字符为几个字节的编码;
  • 当读取到一个字节的首位为1,紧接着读取到一个终结标志0,则该字节显然是非ASCII字符的后续字节(即非首字节)。

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

3.

所以,1~4字节的UTF-8编码看起来分别是这样的:

单字节可编码的Unicode码点值范围十六进制为0x0000 ~ 0x007F,十进制为0 ~ 127;

双字节可编码的Unicode码点值范围十六进制为0x0080 ~ 0x07FF,十进制为128 ~ 2047;

三字节可编码的Unicode码点值范围十六进制为0x0800 ~ 0xFFFF,十进制为2048 ~ 65535;

四字节可编码的Unicode码点值范围十六进制为0x10000 ~ 0x1FFFFF,十进制为65536 ~ 2097151(目前Unicode字符集码点编号的最大值为0x10FFFF,实际尚未编号到0x1FFFFF;这说明作为变长字节数的UTF-8编码其未来扩展性非常强,即便目前的四字节编码也还有大量编码空间未被使用,更不论还可扩展为五字节、六字节……)。

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

4.

上述Unicode码点值范围中十进制值127、2047、65535、2097151这几个临界值是怎么来的呢?

因为UTF-8编码中的每个字节中都含有起到区分和标识之用的前缀码0、110、1110以及10之一,所以1~4个字节的UTF-8编码其实际有效位数分别为8-1=7位(2^7-1=127)、16-5=11位(2^11-1=2047)、24-8=16位(2^16-1=65535)、32-11=21位(2^21-1=2097151),如下表所示:

注:上图中的Unicode range为Unicode码点值范围(也就是Unicode码点编号范围),Hex为16进制,Binary为二进制;Encoded bytes为UTF-8编码中各字节的编码方式(即编码算法),其中,x代表Unicode二进制码点值的单字节或低字节中的低7位或8位、y代表两字节码点值的高字节中的低3位或8位以及三字节码点值的中字节中的8位、z代表三字节码点值的高字节中的低5位。

因此,UTF-8编码的算法简单地来概括就是:首先确定UTF-8编码中各个字节的前缀码;之后再将UTF-8编码中各个字节除了前缀码所占用之外的位,依次分配给Unicode字符码点值二进制中各个位的值。换言之,就是用Unicode字符码点值二进制中各个位的值,依次填充UTF-8编码中的各个字节除了前缀码所占用之外的位。

5.

由于ASCII字符的UTF-8编码使用单字节,而且和ASCII编码一模一样,这样所有原先使用ASCII编码的文档就可以直接解码了,无需进行任何转换,实现了完全兼容。考虑到计算机世界里的英文文档数量之多,这一点意义重大。

而对于其他非ASCII字符,则使用2~4个字节的编码来表示。其中,首字节中前置的“1”的个数代表该字符编码的字节数(如110代表两个字节、1110代表三个字节,以此类推),非首字节之外的剩余后续字节的前两位始终是10,这样就不会与ASCII字符编码(“0”开头)以及非ASCII字符的首字节编码(110或1110等至少两个“1”开头)相冲突。

例如,假设某个字符的首字节是1110yyyy,前置有三个1,说明该字符编码总共有三个字节,必须和后面两个以10开头的字节结合才能正确解码该字符。

6.

由此可知,UTF-8编码设计得非常精巧,虽说不上完美无瑕,但若与后文将要介绍的UTF-16、UTF-32以及前文介绍过的那些ANSI编码相比较,对于其精巧设计将体会得更为深切透彻。因此,UTF-8越来越得到全球一致认可,大有一统字符编码之势

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

(未完待续)

预告:本系列文章下一篇将重点介绍UTF-16编码,敬请关注!】

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

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

相关文章

iphone闪退修复工具_升级 iOS 14.2 微信闪退?iPhone 12 维修贵

原标题:升级 iOS 14.2 微信闪退?iPhone 12 维修贵昨天,苹果推出 iOS 14.2 正式版系统,我相信你们都知道了,主要新增几点功能,并没有针对性解决耗电问题,而对 AirPods Pro 充电进行优化&#xff…

【转】刨根究底字符编码之十三——UTF-16编码方式

1. UTF-16编码方式源于UCS-2(Universal Character Set coded in 2 octets、2-byte Universal Character Set)。而UCS-2,是早期遗留下来的历史产物。 UCS-2将字符编号直接映射为字符编码(CEF,而非CES,详见前文中对现代字符编码模型的解释)&a…

java xml 默认名称空间 xpath_创意产业园办公空间设计

你说想要的样子永远不是现在你的样子,桃花源或许永远在每个人的心底。桃花源办公空间整体外观入口前厅及走廊空间天花板细节桃花源其实是我们每个人或者一群人的乌托邦,一座苏联式的厂房是心中桃花源的开端,光、空、间、穿、行、高、纵、新、…

【转】刨根究底字符编码之十四——UTF-16究竟是怎么编码的

1. 首先要注意的是,代理Surrogate是专属于UTF-16编码方式的一种机制,UTF-8和UTF-32是不用代理的。 如前文所述,为了让UTF-16能继续编码基本平面后面的增补平面中的码点值,于是扩展了UTF-16编码方式。 具体的扩展方法就是为其增…

java环境_配置java环境变量

1.找到此电脑我的电脑右键属性。2.点击高级系统设置。3.点击环境变量。4.点击新建。5.创建变量名JAVA_HOME必须是大写,变量值找到你的jdk的根目录复制下来,然后粘贴进去,点击确定。6.再次点击新建7.创建变量名为path、变量值,找到…

idea+JRebel实现项目热部署

今天发现这个插件,简直神了,太爽了,每次改完代码重启都要等半天,回不去了 第一步:安装插件 第二步:在线生成GUID 网址:在线GUID地址 第三步:打开jrebel 如下所示面板,选…

【转】刨根究底字符编码之十五——UTF-32编码方式

1. UTF-32在UTF目前常用的三种编码方式(UTF-8、UTF-16、UTF-32)中,是最为简单的一种编码方式。UTF-32编码方式不使用任何编码算法将Unicode字符码点值(即编号字符集CCS中的字符编号)转换为码元序列,而是将每个Unicode字符码点值直接表示为一个32位的码元…

小米手机证书信任设置在哪里_小米手机闹钟在哪里?闹钟怎么设置?怎么找到闹钟?...

随着智能手机的大量普及,人们会发现手机里的功能越来越多,绝不像以前那样只能打打电话发发短信那么简单了。而这些功能当中很多我们常用的功能有的人却不会用、不会设置,甚至根本找不到在哪里?比如说手机闹钟这个功能,…

【转】刨根究底字符编码之十六——Windows记事本的诡异怪事:微软为什么跟联通有仇?

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

win10切换输入法快捷键_输入法失灵怎么办?该怎么恢复?

我们都尝试过在使用win10的时候,输入法无法切换,只能打英文不能输入汉字,对于要打字、打游戏来说都是非常麻烦的。所以,当输入法有问题的时候,应该要怎么样修复?主编:渣渣辉,是兄弟就…

【转】刨根究底字符编码【2.0版】(1):开篇

首先跟大家分享一个有趣的亲身经历。有一次,在网上我看到有程序员发了一个帖子,帖子题目乍一看让人感到惊愕,但细一想又让我会心一笑。 这个帖子的题目大致上是这样的:字符编码是不是让程序员最感到恶心的问题? 更有…

数位dp模板 最高位最低位_无纸化办公入门指南(数位板篇)

居家办公的这段时间,你们有没有遇到无纸化办公的问题?作为一名编辑,在我社规定不能寄纸稿的情况下,看电子稿成了常态。如果是word版尚且可以批注,不影响工作效率。但如果是PDF呢?怎样保证改稿的效率&#x…

AQS

1 AQS抽象的队列同步器,AQS定义了一套多线程访问共享资源的同步器框架,许多同步类实现都依赖于它,如常用的ReentrantLock/Semaphore/CountDownLatch 首先AQS维护了一个volatile 修饰的state和一个FIFO的同步队列(多线程争用资源被…

屏幕录像专家6.0_迅捷屏幕录像工具和屏幕录像专家哪个更好用?

随着社会的发展,屏幕录像常常都需要使用,然而有些新手朋友就想知道,到底是电脑中自带的屏幕录像专家好用,还是迅捷屏幕录像工具好用,这两者都是当前使用率比较高的软件,今天小编就为大家分析分析&#xff0…

【转】刨根究底字符编码【2.0版】(2):关键术语解释

上一篇中讲道,字符编码所涉及的面非常广,向下的话,涉及到计算机的底层技术,甚至是硬件实现。 因此,这里就让我们从字符编码涉及到的最基本的术语讲起。大部分术语你可能都已经有了解了,但我们现在从字符编…

Cause: java.sql.SQLSyntaxErrorException: Table ‘Chun.user‘ doesn‘t exist Springboot+MybatisPlus报错

排错:yml配置没问题,可以连接到数据库,导包没问题,数据库里面也有这个库和表, 最终发现是因为表名大小写的问题,因为我直接连接的阿里云服务器上的mysql,而mysql在linux下表名是区分大小写的导…

浏览器字体大小设置_CSS之 浏览器解析样式的过程

阅读本文约需要10分钟大家好,我是你们的导师,经常看我朋友圈的同学应该知道,我每天会在微信上给大家免费提供以下服务!1、长期为你提供最优质的学习资源!2、给你解决技术问题!3、每天在朋友圈里分享优质的技…

angular实现国密算法sm2、sm3和sm4的ts版,基于sm-crypto库实现,前后端实现

ts版,js的话直接根据npm文档调用就可以了! ts提供的方法有问题,所以还换了个思路来实现!而且因为不是nodeJs环境所以const sm4 require(sm-crypto).sm4这个在ts里是报错的导致无法实现,如果是使用的是electron那么使…

【转】.net异步性能测试(包括ASP.NET MVC WebAPI异步方法)

很久没有写博客了,今年做的产品公司这两天刚刚开了发布会,稍微清闲下来,想想我们做的产品还有没有性能优化空间,于是想到了.Net的异步可以优化性能,但到底能够提升多大的比例呢?恰好有一个朋友正在做各种语…

win7关机快捷键_电脑快捷键大全(上)

Windows快捷键1单独按Windows:显示或隐藏“开始”功能表WindowsBREAK:显示“系统属性“对话框WindowsD显示桌面或回复桌面Windows M最小化所有窗口WindowsShiftM:还原最小化的窗口CrtlShiftN:新建文件夹WindowsE:打开“我的电脑”…