盒子
盒子
文章目录
  1. 1. ASCII字符集的编码
  2. 2. Unicode字符集的编码
    1. UTF-8
    2. UTF-16
    3. UTF-32
  3. 3. GB2312和GBK字符集的编码
  4. 4. One more thing
  5. 5. 参考资料

编码?你需要知道的那些事:2-明白编码

这是之前写的文章,因为博客地址换了,重新发布下。

这个系列目前一共四篇文章,之后可能会增加Python3.x关于编码方面的内容。

编码?你需要知道的那些事:1-了解字符集

编码?你需要知道的那些事:2-明白编码

编码?你需要知道的那些事:3-Python2.x为什么有乱码

编码?你需要知道的那些事:4-Java为什么有乱码

更新:

关于Python3 的编码

上文我们说到了字符集,它决定了我们能够看到那些字符,但是字符怎么在计算机内存中表示的可是由编码来决定的喔。

我们知道计算机只认识数字(就是0、1那些东西),可是我们对数字并没有计算机那么敏感,我们还是喜欢看到字符(正如书本上能看到的那样)。这时就需要编码了,当我们需要看到字符时,它会将内存中的数字(一串二进制数)映射为对应的字符来显示给我们看。而只是内存中处理时,任然是一堆数字。

问题来了,怎么映射的呢?简单来说就是查表呗(当然是提前定义好的),用数字去找它对应的字符。那这个表是不是我们上文说到的字符集呢?是,还是不是呢,其实不一定。又迷糊了吧?不过请先记着一句话:一个字符集可以对应很多编码的实现。

那我们分别来看看每种字符集的编码都有哪些实现吧!

1. ASCII字符集的编码

其实就叫ASCII编码,可没有骗你,因为该编码中字符在内存中使用的值与字符集规定编号的一样,也就是说,存储该种字符时,就是将字符集中的编号变为二进制书就好了。(比如1,在字符集的编号为1,人家在内存也是0000 0001)因为一样,所以它对我们还算友善(理错误也不会犯迷糊)。但是下面的一个可就不是这样了。

2. Unicode字符集的编码

上文提到Unicode与UCS合并了,统一了规则,那我们就说说常用的Unicode编码:UTF-8, UTF-16, UTF-32。

UTF-8

UTF-8(8-bit Unicode Transformation Format)是一种针对Unicode的可变长度字符编码,看见了吗,它是可变的,为什么呢?上文提到Unicode字符集一开始使用的是16位,但是不够,而UCS一上来使用31位,太多,而且美国人们也不干了,凭什么我们7位可以表示的东西,你们偏偏要拿这么多位来表示。(浪费,可耻啊!)故UTF-8就是一个折中的办法,看它的名字’UTF-8’像只是用8位是的,但是不是的。你可以理解为它最少使用8位(’UTF-16’和’UTF-32’一样)。所以UTF-8这种编码,字符在内存中的值与Unicode规定的编号是不一定一样的,比如UTF-8是兼容ASCII编码的,对于英文字符,他们将会其编码成1个字节(尽管只用了7位,但是占了8位嘛,正好一个字节),此时UTF-8表示与ASCII字符表示是一样的。但是很多其他的字符编码后可就与其在字符集的编号不一样了,比如’中’在Unicode编号为0x4E2D ,但是在UTF-8编码后却为0xE6B189。现在应该对字符集和编码有了更深的认识。

UTF-16

UTF-16也是Unicode的其中一个使用方式。 UTF-16比起UTF-8,好处在于大部分字符都以固定长度的字节 (2字节) 储存,但UTF-16却无法兼容于ASCII编码。 所以UTF-8对Unicode规定的前65536字符不做转换(还记得前面说的Unicode开始设计的表示字符大小吗?),就是用其编号作为编码后的值,比如’中’在Unicode编号为0x4E2D ,在UTF-16编码后也为0x4E2D。(但是对于之后的值,它也需要做变换),注意通常我们说的Unicode的编码就是它,因为它前65536个字符的编码与编号一致,但是现在要知道的是Unicode只用字符集,而UTF-16才是编码。希望明白了。

UTF-32

UTF-32就厉害了,它对所有的Unicode字符均不做变换,直接使用编号存储!(这样会简单很多),只是这种编码方案太浪费存储空间(就连1个字节就可以搞定的英文字符,它都必须使用4个字节),因而尽管使用起来方便(不需要任何转换),却没有得到普及。

3. GB2312和GBK字符集的编码

还记得上文说的GB2312和GBK字符集吗?其实你也可以叫它们是一种编码(对了,中文Windows的默认编码就是GBK),因为它们也是使用字符集中的编号作为编码值的(和UTF-32一样,直接,暴力),哈哈。不过,现在知道它们的关系了,一览无余呢…

4. One more thing

现在可以回答**UTF-8 ? UTF-16? UTF-32? ISO-8859-*? ASCII? GB2312? GBK? Unicode? UCS?**哪些是字符集,哪些是编码,那些既可以说的字符集又可以说是编码了吧!

  • ASCII GB2312 GBK Unicode UCS 可以说是字符集
  • UTF-8 UTF-16 UTF-32 ISO-8859-*(系列) ASCII GB2312 GBK 都可以说是编码
  • ASCII GB2312 GBK 这些嘛?你懂的。

下篇文章我们讨论一下在哪些地方容易出现编码问题(乱码)呢?

5. 参考资料

Java中的字符集编码入门(二)编码字符集与字符集编码的区别
UTF-8
UTF-16
UTF-32
Mapping codepoints to Unicode encoding forms

支持一下
扫一扫,支持forsigner