本文作者: jsweibo
本文链接: https://jsweibo.github.io/2019/03/20/%E4%BB%80%E4%B9%88%E6%98%AFUTF-8/
摘要
本文主要讲述了:
- 什么是 UTF-8
- 编码规则
- 解码规则
正文
什么是 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 编码。
根据 Unicode 码表,
e的 Unicode 码为65。65处在U+0000 -> U+007F区间,因此使用单字节编码。单字节编码编码规则为
0XXXXXXX,X 只有 7 位。65换算成二进制为01100101,共有 8 位。舍弃
01100101最高位的 0,剩余位依次替换编码规则中的 X。因此
e的二进制 UTF-8 码为01100101,换算成十六进制为65。根据 Unicode 码表,
n的 Unicode 码为6E。6E处在U+0000 -> U+007F区间,因此使用单字节编码。单字节编码编码规则为
0XXXXXXX,X 只有 7 位。6E换算成二进制为01101110,共有 8 位。舍弃
01101110最高位的 0,剩余位依次替换编码规则中的 X。因此
n的二进制 UTF-8 码为01101110,换算成十六进制为6E。根据 Unicode 码表,
g的 Unicode 码为67。67处在U+0000 -> U+007F区间,因此使用单字节编码。单字节编码编码规则为
0XXXXXXX,X 只有 7 位。67换算成二进制为01100111,共有 8 位。舍弃
01100111最高位的 0,剩余位依次替换编码规则中的 X。因此
g的二进制 UTF-8 码为01100111,换算成十六进制为67。综上所述,
eng的二进制 UTF-8 码为01100101 01101110 01100111,换算成十六进制为65 6E 67。
示例:将中文进行 UTF-8 编码。
根据 Unicode 码表,
中的 Unicode 码为U+4E2D。U+4E2D处在U+0800 -> U+FFFF区间,因此使用 3 字节编码。中的二进制 Unicode 码为01001110 00101101。按照从左到右的顺序,替换
1110XXXX 10XXXXXX 10XXXXXX中的 X。中的二进制 UTF-8 码为11100100 10111000 10101101,换算成十六进制为E4 B8 AD。根据 Unicode 码表,
文的 Unicode 码为U+6587。U+6587处在U+0800 -> U+FFFF区间,因此使用 3 字节编码。文的二进制 Unicode 码为01100101 10000111。按照从左到右的顺序,替换
1110XXXX 10XXXXXX 10XXXXXX中的 X。文的二进制 UTF-8 码为11100110 10010110 10000111,换算成十六进制为E6 96 87。综上所述,
中文的二进制 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 解码。
65的二进制为01100101,第 1 位是 0,因此属于单字节编码。根据 Unicode 码表,
01100101对应的字符是e。6E的二进制为01101110,第 1 位是 0,因此属于单字节编码。根据 Unicode 码表,
01101110对应的字符是n。67的二进制为01100111,第 1 位是 0,因此属于单字节编码。根据 Unicode 码表,
01100111对应的字符是g。综上所述,
65 6E 67UTF-8 解码结果为eng。
示例:将E4 B8 AD E6 96 87进行 UTF-8 解码。
E4的二进制为11100100,前 3 位都是 1,因此属于 3 字节编码。B8的二进制为10111000。AD的二进制为10101101。整理获得
11100100 10111000 10101101。按照 3 字节编码规则,参照
1110XXXX 10XXXXXX 10XXXXXX格式,从11100100 10111000 10101101中提取对应的位。获得
01001110 00101101,换算成十六进制为4E 2D。根据 Unicode 码表,
4E 2D对应的字符是中。E6的二进制为11100110,前 3 位都是 1,因此属于 3 字节编码。96的二进制为10010110。87的二进制为10000111。整理获得
11100110 10010110 10000111。按照 3 字节编码规则,参照
1110XXXX 10XXXXXX 10XXXXXX格式,从11100110 10010110 10000111中提取对应的位。获得
01100101 10000111,换算成十六进制为65 87。根据 Unicode 码表,
65 87对应的字符是文。综上所述,
E4 B8 AD E6 96 87UTF-8 解码结果为中文。
参考资料
本文作者: jsweibo
本文链接: https://jsweibo.github.io/2019/03/20/%E4%BB%80%E4%B9%88%E6%98%AFUTF-8/
本文对你有帮助?请支持我
- 本文链接: https://jsweibo.github.io/2019/03/20/%E4%BB%80%E4%B9%88%E6%98%AFUTF-8/
- 版权声明: 除非另有说明,否则本网站上的内容根据署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。