一个巧合
一个朋友在玩打AVG的时候给我抛过来一张图:
这兴趣瞬间就涌上来了嗷,作者贴心的把三个字节分为一组,这让我立马就想到了UTF-8,因为我是清楚中文字符在UTF8中占三个字节的。尝试过直接换算Unicode,得到的是乱码,我对UTF-8的编码规则一窍不通(,看来还得去查查UTF-8的编码规则才行。
UTF-8编码规则
最后找到了阮一峰大佬在2007年的文章:
简单的介绍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 码。
1 | 下表总结了编码规则,字母x表示可用编码的位。 |
据此,如果字节第一位是0,则这一个字节表示一个单独的字符;如果第一位是一,则继续向下看该字节有多少个1,直到第一个0出现之前,有几个1则代表该字符占几个字节。
具体举两个例子:
1.例如我们要编码”你好世界”四个字符,要经过以下步骤:
1)找到四个字符对应的Unicode: u4f60u597du4e16u754c
2)将Unicode转换为二进制(16转2对应四位,不够前补0)
(这里仅以”你”字做演示)
1 | 4 f 6 0 |
3)根据Unicode确定对应UTF-8编码形式
“你”对应Unicode 4F60在符号范围的第三行,则其UTF-8编码形式应该是:
1 | 1110xxxx 10xxxxxx 10xxxxxx |
4)从后向前对应填入二进制,缺位补0,有:
1 | 11100100 10111101 10100000 |
5)以此类推,得到”你好世界”的实际UTF-8编码:
1 | 11100100 10111101 10100000 |
2.转换已知UTF-8编码
对于给定的UTF-8编码,看一个实际例子:
1 | 01001000 |
从0开头则知晓该UTF-8编码一个字节表示一个字符,则0后七位全部为该字符的 Unicode 码,对应关系如下:
1 | BIN HEX CHARACTER |
结束语
这件事其实已经过去很久了,最近才有工夫整理出来。
查阅Unicode标准的时候由衷的感觉万国码真的在尽量照顾到每个语言的需求,真心敬佩。
至于开头的图片…..游戏内容有那么一点NSFW,交给读者自行探索吧XD
参考文献
Unicode标准——东亚部分 http://unicode.org/versions/Unicode4.0.0/ch11.pdf