一个巧合

一个朋友在玩打AVG的时候给我抛过来一张图:
1
这兴趣瞬间就涌上来了嗷,作者贴心的把三个字节分为一组,这让我立马就想到了UTF-8,因为我是清楚中文字符在UTF8中占三个字节的。尝试过直接换算Unicode,得到的是乱码,我对UTF-8的编码规则一窍不通(,看来还得去查查UTF-8的编码规则才行。

UTF-8编码规则

最后找到了阮一峰大佬在2007年的文章:

阮一峰-字符编码笔记:ASCII,Unicode 和 UTF-8

简单的介绍UTF-8的编码规则:

一个重要的前提"UTF-8是Unicode的实现方式之一",它最大的特点就是实现了变长编码,根据不同字符从1-4字节间变换,分两种情况讨论其编码形式:

1.对于单字节的符号

单字节符号,例如英文字母,将字节的第一位设为0,后面7位对应该字符的Unicode码,空位前补0。因此对于英文字符,UTF-8与ASCII码在二进制表现上是相同的。

2.对于多字节的符号

对于 n 字节的符号 ( n > 1 ) ,第一个字节的前 n 位都设为1,第 n + 1 位设为 0 ,后面字节的前两位一律设为 10 。剩下的没有提及的二进制位,全部为这个符号的 Unicode 码。

下表总结了编码规则,字母x表示可用编码的位。

Unicode符号范围      |      UTF-8编码方式
(十六进制)           |     (二进制)
--------------------+---------------------------------------------
0000 0000-0000 007F | 0xxxxxxx
0000 0080-0000 07FF | 110xxxxx 10xxxxxx
0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

据此,如果字节第一位是0,则这一个字节表示一个单独的字符;如果第一位是一,则继续向下看该字节有多少个1,直到第一个0出现之前,有几个1则代表该字符占几个字节。

具体举两个例子:

1.例如我们要编码"你好世界"四个字符,要经过以下步骤:

1)找到四个字符对应的Unicode: \u4f60\u597d\u4e16\u754c
2)将Unicode转换为二进制(16转2对应四位,不够前补0)
(这里仅以"你"字做演示)

 4     f     6     0
 ↓     ↓     ↓     ↓
0100  1111  0110  0000

3)根据Unicode确定对应UTF-8编码形式
"你"对应Unicode 4F60在符号范围的第三行,则其UTF-8编码形式应该是:

1110xxxx 10xxxxxx 10xxxxxx

4)从后向前对应填入二进制,缺位补0,有:

11100100 10111101 10100000

5)以此类推,得到"你好世界"的实际UTF-8编码:

11100100 10111101 10100000
11100101 10100101 10111101
11100100 10111000 10010110
11100111 10010101 10001100

2.转换已知UTF-8编码

对于给定的UTF-8编码,看一个实际例子:

01001000 
01000101
01001100 
01001100
01001111
01010111
01001111
01010010
01001100
01000100

从0开头则知晓该UTF-8编码一个字节表示一个字符,则0后七位全部为该字符的 Unicode 码,对应关系如下:

BIN          HEX   CHARACTER
0100 1000 →  48 →     H
0100 0101 →  45 →     E
0100 1100 →  4C →     L  
0100 1100 →  4C →     L
0100 1111 →  4F →     O
0101 0111 →  57 →     W
0100 1111 →  4F →     O
0101 0010 →  52 →     R
0100 1100 →  4C →     L
0100 0100 →  44 →     D

结束语

这件事其实已经过去很久了,最近才有工夫整理出来。
查阅Unicode标准的时候由衷的感觉万国码真的在尽量照顾到每个语言的需求,真心敬佩。

至于开头的图片.....游戏内容有那么一点NSFW,交给读者自行探索吧XD

参考文献

Unicode标准——东亚部分 http://unicode.org/versions/Unicode4.0.0/ch11.pdf

阮一峰——字符编码笔记:ASCII,Unicode 和 UTF-8 https://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html

千千秀字 https://www.qqxiuzi.cn/

ASCII码对照表 https://www.habaijian.com/