最近用到了etcd的一个kv.proto生成的mvccpb.KeyValue结构体,里面的Value是[]byte类型的,可是用string()始终不能完美地打印在控制台上,因此顺便总结了一下字符编解码相关知识点。
ASCII/Unicode 编码
ASCII是一开始美国人自己玩电脑的时候用的,英文又比较少,所以ASCII整体设计特别简单,一个字节没用完就囊括了所有要用的字符。但是后来欧洲人和中国人也想玩计算机,这个ASCII实在不够用,于是又自己捣鼓起了ISO,GBK。因为欧洲人和中国人玩的时候,也要兼容ASCII(毕竟那些字符自己也用得上),所以前127号没变。但是128-256号的变化就大了,尤其是欧洲国家,同一个位置代表不同的字符,严重阻碍了交流。
后来互联网出现,统一字符集是大势所趋,于是有人牵头弄了个Unicode,势必要囊括所有你能想得到的字符。Unicode提供的是一个映射表,字符-》Unicode Point。比如U+0639表示阿拉伯字母Ain,U+0041表示英语的大写字母A,U+4E25表示汉字严。这个相当于一个统一规范,大家都别争了,统一按这个标准来。
Utf-8
但是这个U+开头的代码,并没有实际规定计算机的存储格式。换句话说,Unicode提供的是抽象编码,不是计算机实际存储的格式。于是Utf-8就出现了。这是一种变字节(1-4)的编码格式,可以根据Unicode编码的位置,调整分配的字节数量。比如1,你不用分配4个字节,只用1个就够了。这种比较人性化,减少了文本的体积。
Utf-8 计算的过程