什么是UTF-8


本文作者: jsweibo

本文链接: https://jsweibo.github.io/2019/03/20/%E4%BB%80%E4%B9%88%E6%98%AFUTF-8/

摘要

本文主要讲述了:

  1. 什么是 UTF-8
  2. 编码规则
  3. 解码规则

正文

什么是 UTF-8

UTF-8 是一种变宽的 Unicode 字符编码方案。它使用 1-4 个字节编码 Unicode 字符

UTF-8 向后兼容ASCII,因此属于EASCII的一种

注:UTF-8 编码不区分大端小端

编码规则

  • 根据 Unicode 码表,查询字符的 Unicode 码。
  • 根据 Unicode 码所在的区间,按照从左到右的顺序,将字符的二进制 Unicode 码替换掉编码规则中的 X。
Unicode Number Range UTF-8
U+0000 -> U+007F 0XXXXXXX
U+0080 -> U+07FF 110XXXXX 10XXXXXX
U+0800 -> U+FFFF 1110XXXX 10XXXXXX 10XXXXXX
U+10000 -> U+10FFFF 11110XXX 10XXXXXX 10XXXXXX 10XXXXXX

示例:将eng进行 UTF-8 编码。

  1. 根据 Unicode 码表,e的 Unicode 码为65

  2. 65处在U+0000 -> U+007F区间,因此使用单字节编码。

  3. 单字节编码编码规则为0XXXXXXX,X 只有 7 位。

  4. 65换算成二进制为01100101,共有 8 位。

  5. 舍弃01100101最高位的 0,剩余位依次替换编码规则中的 X。

  6. 因此e的二进制 UTF-8 码为01100101,换算成十六进制为65

  7. 根据 Unicode 码表,n的 Unicode 码为6E

  8. 6E处在U+0000 -> U+007F区间,因此使用单字节编码。

  9. 单字节编码编码规则为0XXXXXXX,X 只有 7 位。

  10. 6E换算成二进制为01101110,共有 8 位。

  11. 舍弃01101110最高位的 0,剩余位依次替换编码规则中的 X。

  12. 因此n的二进制 UTF-8 码为01101110,换算成十六进制为6E

  13. 根据 Unicode 码表,g的 Unicode 码为67

  14. 67处在U+0000 -> U+007F区间,因此使用单字节编码。

  15. 单字节编码编码规则为0XXXXXXX,X 只有 7 位。

  16. 67换算成二进制为‭01100111,共有 8 位。

  17. 舍弃‭01100111最高位的 0,剩余位依次替换编码规则中的 X。

  18. 因此g的二进制 UTF-8 码为‭01100111,换算成十六进制为67

  19. 综上所述,eng的二进制 UTF-8 码为0‭1100101 0‭1101110 ‭01100111,换算成十六进制为‭65 6E 67‬

示例:将中文进行 UTF-8 编码。

  1. 根据 Unicode 码表,的 Unicode 码为U+4E2D

  2. U+4E2D处在U+0800 -> U+FFFF区间,因此使用 3 字节编码。

  3. 的二进制 Unicode 码为01001110 00101101

  4. 按照从左到右的顺序,替换1110XXXX 10XXXXXX 10XXXXXX中的 X。

  5. 的二进制 UTF-8 码为11100100 10111000 10101101,换算成十六进制为E4 B8 AD‬

  6. 根据 Unicode 码表,的 Unicode 码为U+‭6587

  7. U+‭6587处在U+0800 -> U+FFFF区间,因此使用 3 字节编码。

  8. 的二进制 Unicode 码为01100101 10000111

  9. 按照从左到右的顺序,替换1110XXXX 10XXXXXX 10XXXXXX中的 X。

  10. 的二进制 UTF-8 码为11100110 10010110 10000111,换算成十六进制为E6 96 87‬

  11. 综上所述,中文的二进制 UTF-8 码为11100100 10111000 10101101 ‬11100110 10010110 10000111,换算成十六进制为‭E4 B8 AD‬ ‭E6 96 87‬

解码规则

  • 将十六进制的 UTF-8 码换算成二进制,左起找 n 位连续的 1。若 n=0 则为单字节编码,n=1 则递归前一个字节,n=2 则为 2 字节编码,n=3 则为 3 字节编码,n=4 则为 4 字节编码。
  • 根据编码规则,连续取出 n 个字节,换算成二进制的形式,将 UTF-8 编码规则中对应的位抽取出来组成 Unicode 码点。
  • 按照 Unicode 码表,反查对应的字符。
Unicode Number Range UTF-8
U+0000 -> U+007F 0XXXXXXX
U+0080 -> U+07FF 110XXXXX 10XXXXXX
U+0800 -> U+FFFF 1110XXXX 10XXXXXX 10XXXXXX
U+10000 -> U+10FFFF 11110XXX 10XXXXXX 10XXXXXX 10XXXXXX

示例:将‭65 6E 67‬进行 UTF-8 解码。

  1. 65的二进制为‭01100101‬,第 1 位是 0,因此属于单字节编码。

  2. 根据 Unicode 码表,‭01100101‬对应的字符是e

  3. 6E的二进制为‭01101110‬,第 1 位是 0,因此属于单字节编码。

  4. 根据 Unicode 码表,‭01101110‬对应的字符是n

  5. 67‬的二进制为‭01100111‬,第 1 位是 0,因此属于单字节编码。

  6. 根据 Unicode 码表,‭01100111‬对应的字符是g

  7. 综上所述,65 6E 67UTF-8 解码结果为eng

示例:将‭E4 B8 AD‬ ‭E6 96 87‬进行 UTF-8 解码。

  1. E4的二进制为‭11100100‬,前 3 位都是 1,因此属于 3 字节编码。

  2. B8的二进制为‭10111000‬

  3. AD‬的二进制为‭10101101‬

  4. 整理获得‭11100100‬ ‭10111000‬ ‭10101101‬

  5. 按照 3 字节编码规则,参照1110XXXX 10XXXXXX 10XXXXXX格式,从‭11100100‬ ‭10111000‬ ‭10101101‬中提取对应的位。

  6. 获得01001110 00101101,换算成十六进制为4E 2D

  7. 根据 Unicode 码表,4E 2D对应的字符是

  8. ‭E6的二进制为‭11100110‬,前 3 位都是 1,因此属于 3 字节编码。

  9. 96的二进制为‭10010110‬

  10. 87‬的二进制为‭10000111‬

  11. 整理获得‭11100110‬ ‭10010110‬ ‭10000111‬

  12. 按照 3 字节编码规则,参照1110XXXX 10XXXXXX 10XXXXXX格式,从‭11100110‬ ‭10010110‬ ‭10000111中提取对应的位。

  13. 获得01100101 10000111,换算成十六进制为65 87

  14. 根据 Unicode 码表,65 87对应的字符是

  15. 综上所述,‭E4 B8 AD‬ ‭E6 96 87‬UTF-8 解码结果为中文

参考资料

本文作者: jsweibo

本文链接: https://jsweibo.github.io/2019/03/20/%E4%BB%80%E4%B9%88%E6%98%AFUTF-8/


本文对你有帮助?请支持我


支付宝
微信