之前对emoji没怎么关注过,只有大约印象和编码有关,今天花了一点时间去看了一下emoji如何编码的。 先贴个知乎回答-Unicode 和 UTF-8 有什么区别? - 邱昊宇的回答 - 知乎 里面涉及两个概念:
字符集:为每一个「字符」分配一个唯一的 ID(学名为码位 / 码点 / Code Point)
编码规则:将「码位」转换为字节序列的规则(编码/解码 可以理解为 加密/解密 的过程)
unicode码是是一种字符集(类似的还有gbk),而utf-8是一种编码规则(类似的还有utf-16等)
先去查找相关资料:
现在就够知识进行实验了: 先去拷贝一个表情放到浏览器上来试试:?(其实我们都被计算机视为一种字节流,包括这些文字也都是)
就这个笑脸为例子吧。
首先介绍一下这个笑脸:
这个笑脸占4个字节,用十六进制表示可表示为:0xf0,0x9f,0x98,0x80。
不信你可以使用世界上最好的语言来打包试试:$str = pack('cccc',0xf0,0x9f,0x98,0x80);,打印这个$str,然后在浏览器中打开就可以看到上面这个笑脸了。
那么我们再来查一下这个笑脸在unicode中的码是什么呢?
查到了!就是:1F600,一眼能看得出它也是一个十六进制的数。
这个和刚才上面那个0x f0 9f 98 80差的也太远了吧!
不要着急,区位码(1F600)和 utf-8字节流之间还没开始转换呢,根据百度来的编码规则(这个百度来的和谷歌来的都是一样的,是真的!)
先把十六进制都转成二进制,再看就比较容易:
1F600转为二进制:0001 1111 0110 0000 0000
0x f0 9f 98 80转为二进制: 1111 0000 1001 1111 1001 1000 1000 0000
然后我们看下转换规则,
文献规则中说到:“Unicode转换为UTF-8时,可以将Unicode二进制从低位往高位取出二进制数字,每次取6位,……不足8位用0填补。”,根据这个规则就是可以进行编码了:
1111 0 000
10 01 1111
10 01 1000
10 00 0000 //
这里转换完毕正好就得到 1111 0000 1001 1111 1001 1000 1000 0000。