本文作者: 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 67
UTF-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 87
UTF-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) 进行许可。