かかってこいよ NakamuraEmi
  1. 1 かかってこいよ NakamuraEmi
  2. 2 Quiet Storm Lyn
  3. 3 Last Surprise Lyn
  4. 4 Libertus Chen-U
  5. 5 One Last You Jen Bird
  6. 6 The Night We Stood Lyn
  7. 7 Hypocrite Nush
  8. 8 Warcry mpi
  9. 9 Time Bomb Veela
  10. 10 Life Will Change Lyn
  11. 11 Flower Of Life 发热巫女
2017-04-26 18:35:16

从下到上的字符编码总结

最近碰到一些数据传输问题,什么unicode,UTF-8,base64等等一堆数据转换相关的概念分不清楚,索性做一个从下到上的总结,以后自己查起来也方便。


字节

在计算机内部,所有的信息最终都是一个二进制的字符串,每一个二进制位(bit)都有0和1两种状态。不知道是谁规定的,有人决定用8个二进制位来组合表示不同的状态。因此8个二进制位就可以组合出256种状态,状态变来变去,早期的计算机就用来处理这256种状态的变化。每种状态就称为1个字节(byte),也是网络传输信息的最小单位。


ASCII码

好了,我们现在有了256种状态,那么要传递信息我们必然要为这256种状态赋予意义。开始计算机只在美国用,他们把编号从0开始的32种状态规定了特殊又重要的用途。比如换行,打印等。于是前32种状态就叫控制码。然后为了表达文字信息,他们又把标点符号,数字,大小写字母分别用连续的字节状态表示,一直编到了第128种状态,也就是0~127字节。计算机就可以用不同的字节表示英语文字和一些特殊的控制了。这就是ASCII码,这128种状态只占用了一个字节的后7位,最前面的一位统一规定为0。


拓展字符集

后来越来越多的国家开始使用计算机,但是英语用128个符号就够了,其他语言是不够的。于是一些欧洲国家决定127之后的空位用来表示新的字母,符号,还加入了画表格需要的各种形状,一直编到了最后一个状态255。从128到255这一区间的状态就叫做拓展字符集


GBK

等到我们中国人用到计算机时,已经没有可以利用的字节供我们表示汉字了,而且常用汉字有6000多个,继续这么表示也不是办法。于是我们把拓展字符集直接取消掉,规定小于127号的字符意义仍然不变,但当两个大于127号的字符连在一起时就表示一个汉字,前面一个字节称为高字节,后面一个字节称为低字节,这样我们组合除了大约7000多个简体汉字,还把数学符号,罗马字母,日文假名等等都编进去了,连本来就有的数字,标点,字母等都重新编写了两个字节长的编码,这就是全角字符,127号之前的就叫半角字符了。这种实现方案可行,我们称之为GB2312,是对ASCII的中文拓展。

但是中国的汉字太多了,很快GB2312的表示方式就不够用了,于是干脆不再要求低字节是127号之后的状态,只要第一个字节是大于127就规定这是一个汉字的开始。这样拓展之后的编码方案称为GBK标准,后来又增加了一些少数名族字符,GBK拓展成了GB18030,这一系列汉字编码标准我们统称为DBCS


unicode

由于各个国家语言符号不一样,所以全世界有着各种各样的编码标准,同一个二进制数字经常被解释成不同的符号。因此想要打开文本文件就必须知道它的编码方式,否则就会出现乱码。可以想象,如果有一种编码方式将世界上的所有符号都给予一个独一无二的编码就可以解决交流问题。这就是ISO组织的目的,这个国际标准化组织决定解决这个问题,他们废除了所有地区性编码方案,重新搞了个包括地球上所有符号的编码——unicode

ISO规定必须用两个字节,也就是16位表示所有的字符。对于ASCII的字符unicode保持其原编码不变,只是将8位拓展为16位,所以高8位永远是0,其他字符全部重新编码。

unicode存在的问题

需要注意的是unicode只是符号集,只规定了符号向二进制代码的转化,却没有规定二进制代码应该如何存储。比如有些符号可以用3个字节或4个字节去存储,也可以用1个字节存储。

这就导致了两个问题:第一个问题是怎么区别unicode和ASCII编码?三个字节有可能按照unicode表示一个符号,也可能按照ASCII表示三个符号。

第二个问题是英文字母只用一个字节就够了,如果用两个或三个字节去存储,对于存储空间是很大的浪费。


UTF-8

为了解决unicode的以上问题,使其能自由的在网络上传输,于是面向传输的UTF标准出现了。UTF-8就是每次以8个位传输数据。它使用1~4个字节存储一个unicode符号。转换规则如下:

  1. 对于单字节的符号,第一位设置为0,后面7位为unicode码。因此UTF-8编码完全覆盖了ASCII码。
  2. 对于n字节的符号(n > 1),第一个字节的前n位设置为1,第n+1位设置为0,后面字节的前两位全设置为10。剩下的二进制位全部为这个符号的unicode码填充。

Base64

base64编码常用在处理复杂数据的场合,用来传输,存储一些二进制数据,比如图片,邮件等。其之所以称为base64是因为使用64个字符(不包括作为垫字的=)来对任意数据进行编码,这64个字符是ASCII编码的子集并且可打印。比较特殊的是最后两个字符,对最后两个字符的选择不同又有很多变种,比如base64 URL编码。

该编码本质上是将二进制数据转化为文本数据的方案,对于非二进制数据,先将其转化为二进制形式然后每连续6比特计算其十进制值并对应索引表找到对应字符得到最终的文本字符串。

-- EOF --

添加在分类「 前端开发 」下,并被添加 「操作系统」 标签。