我的字符编码总结

刚开始接触mac osx这类系统的时候,使用default的zip解压,很容易出现乱码问题。每次我使用默认设置解压一个压缩文件的时候,如果这个文件来自一个中国人的windows电脑的话,十有八九肯定是乱码,想都不用想! 一开始我还没有使用[The Unarchiver]这款软件的时候,用着各种不爽,出现次数多了,火气就起来了(信不信我砸了你,就是这种感觉)

不过,生气归生气,还是要研究下为什么会出现这种问题的!所以,随后我查阅了好多网上的资料,也看了一些写的比较好的blog学习了下,算是将困扰我很久的字符编码问题给解决了(弄懂一个东西后还真是感觉心情舒畅啊=v=)

其实mac是一直采用utf-8的字符编码,而一般我们中文环境下的windows系统是采用gbk作为默认的字符编码的(现在应该最新的是gb18030,全称叫China National Chinese)。看到这里如果没能反应过来乱码和这两个东西有什么关系的话,没关系,因为接下来我就回来解释下为什么了!

先从二进制说起


我们都知道,计算机里使用的都是二进制码,即0,1这两个数字。我们常说的一个字节(byte),其实代表了一个八位(bit)的二进制数字。比如数字32,我们就可以很容易的得出它的二进制表示,

1
2
3
4
5

0010 0000

1 * 2^5 = 32;
//有关进制之间的互相转换,这个我就不在这里提及了,网上搜一大堆呢,自己学去

可以看到十进制数32,刚好可以由一个八位的二进制数表示(其实只要六位,前两位的0都没有用到,不过八位刚好凑成一个字节的长度,所以我这里这么说)
所以我们在电脑上看到的数字32,在计算机来看,按照上面的这里换算编码的话,就是0010 0000这一串东西了。

ASCII码


ASCII码是比较简单的一种编码,它就是用八位的二进制数来表示一些字符的,我们可以知道一个八位的二进制,可以有2^8种,即256种。

1
2
3
4
5
6
7
8
9
0000 0000
0000 0001
0000 0010
0000 0100
0000 1000
.
.
.
1111 1111


从0000 0000到1111 1111,256种情况,可以分别代表256种字符。

不过,当时这玩意就是做给英文操作系统用的,哪里需要256种,128种其实就够了。所以ASCII码的第一位都是0,这样就把种数变成了128种。

控制字符

ASCII的前32个加上第127个,代表的都是控制符号,这些符号主要用于一些特殊情况,我们作为使用者是不怎么会用到的,这里不会细讲,真的很想了解的同学,please google一下

可显示字符

既然前32个都用来作为控制符号用,那么其他的当然是为我们所用了,比如26个个英文字母,abcdefg…..都有对应的ASCII码。(对于程序员来说,知道A是65,a是97,应该是比较重要的哦=v=)

不管怎么说,ASCII码,这货能干的活仅限于美国佬的computer。如果说要用它来表示我们博大精深的中文汉字,256种哪能够呢。哈哈哈哈

所以我们接下来来讲讲和中文汉字编码有关的字符编码方式

Unicode字符编码


再说中文汉字的字符编码之前,先说说Unicode这个字符编码吧!

把Unicode说成是一个字符编码是不对的,Unicode其实是字符编码的一个国际标准,其实现方式有很多种,比如utf-8,utf-16,utf-32。

Unicode使用了16位的二进制数,所以理论上是可以表示2^16次(65536种),这么多基本满足了各类语言对不同符号的需求。

不过有时候确实16位也不够,那么我们就32位吧,就是4个字节,2^32,这么多总可以了吧,事实上,确实是够了。

不过当变成32位的时候,又出现了一些问题,比如我们只是简单的表示一个英文字母a,我们如果用32位来表示的话,前面不都是0吗,这些有必要存储吗?没必要

所以为了让这些0可以去掉,来节省我们的存储空间,所以Unicode的实现方式就有好多种了。

接下来我们重点就来看看utf-8,这是一个互联网时代通用的unicode实现方式,如果大家都统一用utf8的话,相信乱码问题也会少很多呢

utf-8


那年我们的网站制作过程全程采用utf8真是太好了!gbk?gb18030?那是什么,我不知道,啊哈哈哈哈

utf8的出现原因是这样的。比如我们要表示一个英文单词a的时候,只需要八位就可以了,那么使用16位的Unicode来表示,前八位不就都变成0,然而这些0是没有意义的,所以当我们仍然采用Unicode的16位进行传输一些英文单词的时候,要传输的内容不就多了一倍,而且这多出来的一倍还特么的是一堆没用的零蛋!

咳咳,所以说我们要缩短用Unicode表示的英文单词的字符长度!所以就有了utf-8

utf-8是Unicode在传输的时候使用的一种实现方式!(注意不要以为utf8是一个字符集,错!它只是encoding层次的!utf8的二进制数可以转换回Unicode形式,然后查找Unicode字符集来转译成我们看到的字符!)

下面我展示一下utf8的编码规则:

1
2
3
4
5
6
7
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

1)对于单字节的符号,字节的第一位设为0,后面7位为这个符号的unicode码。因此对于英语字母,UTF-8编码和ASCII码是相同的。
2)对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10。剩下
的没有提及的二进制位,全部为这个符号的unicode码。

以上两点就是utf-8的规则!是不是很简单!

不过不要被其表面的简单所蒙骗了,Unicode虽然好用,不过你如果是一名web开发人员的话,就一定会在意流量问题!

如果从流量问题角度出发!如果你使用utf8,那么对于中文来说,你的流量会增加50%。因为大部分常用的中文,使用两个字节就可以表示了,如果采用utf8的话,utf8按上面的规则,一个中文字会变成3个字节,这不就多了一个字节的空间了吗!

还有另一个问题!关于现在有些网站仍在使用的gbk,这个怎么说呢,应该算是一个历史遗留问题了吧。我相信对于开发人员来说,一定更喜欢utf8,毕竟省事!(不过从流量角度出发,gbk还是有优势的!不过多出50%的流量)

在utf8后还有utf16,utf32,可以理解为是对不同情况下的utf8的拓展

所以最开始说的乱码问题


mac电脑默认采用utf8,而很多中文windows系统的文件采用gbk,一个两字节,一个1~3字节,有自己的算法,所以在mac电脑上解压的zip文件默认用Unicode(USC-2)或者utf8 或者utf16le等等(大端be,小端le)来进行解压的时候,自然而然就变成了乱码了!

Live2d