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开头(以区别于单字节编码以及多字节编码的首字节)。

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

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)

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

4.

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二进制码点值的低8位、y代表两字节码点值的高8位及三字节码点值的中8位、z代表三字节码点值的高8位。

5.

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

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

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

6.

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

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

(未完待续)

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

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

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

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

  2. sql 入门经典(第五版) Ryan Stephens 学习笔记 (第六,七,八,九,十章,十一章,十二章)

    第六章: 管理数据库事务 事务 是 由第五章 数据操作语言完成的  DML ,是对数据库锁做的一个操作或者修改. 所有事务都有开始和结束 事务可以被保存和撤销 如果事务在中途失败,事务中的任何部分都不 ...

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

    UTF-16究竟是怎么编码的 1. 首先要注意的是,代理Surrogate是专属于UTF-16编码方式的一种机制,UTF-8和UTF-32是不用代理的. 如前文所述,为了让UTF-16能继续编码基本平 ...

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

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

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

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

  6. SQL注入之Sqli-labs系列第三十二关(基于宽字符逃逸注入)

    开始挑战第三十二关(Bypass addslashes) 0x1查看源代码 (1)代码关键点 很明显,代码中利用正则匹配将 [ /,'," ]这些三个符号都过滤掉了 function che ...

  7. 利用zxing制作彩色,高容错,支持中文等UTF编码的QR二维码图片

    利用zxing制作彩色,高容错,支持中文等UTF编码的QR二维码图片.代码如下 import java.awt.Color;import java.io.File;import java.util.H ...

  8. 【JAVA编码】 JAVA字符编码系列二:Unicode,ISO-8859,GBK,UTF-8编码及相互转换

    http://blog.csdn.net/qinysong/article/details/1179489 这两天抽时间又总结/整理了一下各种编码的实际编码方式,和在Java应用中的使用情况,在这里记 ...

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

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

随机推荐

  1. 第一个 lua 程序

    第一个 lua 程序 lua 提供一个交互式编程模式, 直接在命令行输入 lua 开启 $ lua > -- 此处可以输入 lua 程序 lua 脚本执行时的 2 种方式 lua + lua 脚 ...

  2. [.NET] 《C# 高效编程》(一) - C# 语言习惯

    C# 语言习惯 目录 一.使用属性而不是可访问的数据成员 二.使用运行时常量(readonly)而不是编译时常量(const) 三.推荐使用 is 或 as 操作符而不是强制类型转换 四.使用 Con ...

  3. jquery使用CSS3实现文字动画效果插件Textillate.js

    Textillate是一款基于jquery的使用CSS3实现文字动画的小巧插件.Textillate.js集成了一些很棒的使用CSS3动画效果的 JavaScript 库,您可非常轻轻松地把这些动画效 ...

  4. LRU Cache java实现

    要求: get(key):如果key在cache中,则返回对应的value值,否则返回null set(key,value):如果key不在cache中,则将该(key,value)插入cache中( ...

  5. Nginx 常用配置整理

    #定义Nginx运行的用户和用户组 user www www; #nginx进程数,建议设置为等于CPU总核心数. worker_processes 8; #全局错误日志定义类型,[ debug | ...

  6. OA系统在实际应用中可发挥出的协同应用价值

    OA软件引进国内已有二十多年,早期的OA软件更多地是扮演一个"文秘"的角色,只进行一些基本的行政事务处理,创造的价值不大.但随着OA软件理论和技术的日趋成熟,OA软件摆脱了原有的局 ...

  7. OC中的单例

    概念 单例模式的意图是类的对象称为系统中唯一的实例,提供一个访问点,供客户类共享资源 什么情况下使用单例 )类只能由一个实例,而且必须从一个为人熟知的访问点对其进行访问,比如工厂方法 )这个唯一的实例 ...

  8. NodeJS+Express+MongoDB 简单实现数据录入及回显展示【适合新人刚接触学习】

    近期在看NodeJS相关 不得不说NodeJS+Express 进行网站开发是很不错,对于喜欢玩JS的来说真是很好的一种Web开发组合 在接触NodeJS时受平时Java或者C#中API接口等开发的思 ...

  9. sysbench压测mysql

    MySQL数据库测试 select   1.先创建数据库test,再准备数据 time /usr/local/sysbench/bin/sysbench --test=oltp --num-threa ...

  10. linux下归档、解压缩工具:tar命令

    tar是一个类似于windows下的解压缩工具,可以将一大堆文件或目录打包成一个文件,还可以通过特定选项使用压缩工具进行解压缩. 语法: tar (选项) (参数) 常用选项: -c:创建打包文件. ...