编码原理理解之「UTF-8」
一、什么是UTF-8
UTF-8(8位元,Universal Character Set/Unicode Transformation Format)是针对Unicode的一种可变长度字符编码。它可以用来表示 Unicode 标准中的任何字符,而且其编码中的第一个字节仍与ASCII 相容,使得原来处理 ASCII 字符的软件无须或只进行少部份修改后,便可继续使用。因此,它逐渐成为电子邮件、网页及其他存储或传送文字的应用中,优先采用的编码。
总结下来,UTF8 有如下特点:
1)是 unicode 的一种实现方式;
2)是一种变长编码标准;
3)可以与 ASCII 码有效兼容;
4)应用超级广泛编码标准。
二、UTF-8 的编码规则
我们讲,UTF-8 是 unicode 的一种实现方式,那么,想要对一个字符进行 UTF-8 编码,首先我们要知道这个字符的 unicode 编码(字符的 unicode 编码是约定好的,全球统一不变的)。拿 unicode 编码的方式很简单,网上有很多 工具 可以做到。
接下来针对不同的 unicode 符号范围,utf-8 编码实际占用的字节数可能 1~4 字节不等👇
unicode 符号范围 | utf-8 编码方式
00000000 ~ 0000007F | 0xxxxxxx
00000080 ~ 000007FF | 110xxxxx 10xxxxxx
00000800 ~ 0000FFFF | 1110xxxx 10xxxxxx 10xxxxxx
00010000 ~ 0010FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
总结下来,针对UTF8,编码规则其实只有两条:
1)单字节规则: 对于 单字节 的符号,字节的第一位(最高位)设为 0,后面 7 位为这个符号的 unicode 码。
2)n字节规则: 对于 n 字节的符号(n>1),第一个字节的前 n 位都设为 1,第 n+1 位设为 0,后面字节的前两位一律设为 10。剩下的没有提及的二进制位,全部为这个符号的 unicode 码。
三、UTF-8 的编码举例
A
-- unicode --> \u0041(1000001)
-- UTF-8 --> 0x41(0 1000001)
真
-- unicode --> \u771f(01110111 00011111)
-- UTF-8 --> 0xe79c9f(1110 0111 10 011100 10 011111)
开
-- unicode --> \u5f00(01011111 00000000)
-- UTF-8 --> 0xe5bc80(1110 0101 10 111100 10 000000)
心
-- unicode --> \u5fc3(01011111 11000011)
-- UTF-8 --> 0e5bf83(1110 0101 10 111111 10 000011)
以 「真」 举例,我们查到 「真」 的 unicode 编码是 \u771f( \u 只是unicode 的编码标记,其后面跟的还是 16 进制数),发现真的编码范围是 0x0800 ~ 0xffff 间,故选择 3字节 的编码方式👇
00000800 ~ 0000FFFF | 1110xxxx 10xxxxxx 10xxxxxx
我们将 0x771f 转化为2进制(共16位),并分成 4、6、6 三组,填入👆编码方式的「x」 的位置,得到 1110 0111 10 011100 10 011111,至此完成「真」 的 utf-8 编码,转化为 16 进制描述即:0xe79c9f。
四、体验
那么,有mac的小伙伴可以试试小编提供的一套基于iOS的编码理解工程。可以快速打印出一段文本编码的数据结果(16进制、2进制都有),示例如下:
/* 代码示例 */
cytLogStringData(@"今儿个真开心!", NSUTF8StringEncoding);
/* 打印结果 */
今 : 3
e4 bb 8a
11100100 10111011 10001010
儿 : 3
e5 84 bf
11100101 10000100 10111111
个 : 3
e4 b8 aa
11100100 10111000 10101010
真 : 3
e7 9c 9f
11100111 10011100 10011111
开 : 3
e5 bc 80
11100101 10111100 10000000
心 : 3
e5 bf 83
11100101 10111111 10000011
! : 3
ef bc 81
11101111 10111100 10000001
e4 bb 8a e5 84 bf e4 b8 aa e7 9c 9f e5 bc 80 e5 bf 83 ef bc 81
11100100 10111011 10001010 11100101 10000100 10111111 11100100 10111000 10101010 11100111 10011100 10011111 11100101 10111100 10000000 11100101 10111111 10000011 11101111 10111100 10000001
字符数:7
字节数:21
每个字符平均占用: 3.00字节
git地址:https://github.com/chrisYooh/CYEncoding.git
对你有帮助的话记得帮小编点个 「Star」 哦!😊✨✨✨