0%

字符编码的通俗理解

。。。

1. 字符集

  用到的字集,比如中文,比如英文26个字母,比如日文,都是一个个字符集,全球所有字符都合在一起也是个字符集。


2. 字符编码

  要把字符集表示到计算机中,计算机只认识数字,更确切来说只认识0、1,因此需要把字符集先编码成数字,再转换成01放到计算机中,比如我规定了一套字符编码,规定:

1
2
3
// 我的字符编码表
你-1
好-2

  也就是说,数字1就代表“你”,数字2就代表“好”。以后我遇见“12”就知道这个是“你好”的意思,计算机如果用我这个编码,遇到“12”就指挥显示器打印出“你好”两个字的像素点,这样就能被人们看到了。
  我用的是这一套编码,另一个人suntus说我不认可,我要用另一套编码:

1
2
3
4
5
// suntus的字符编码表
笨-1
蛋-2
你-8
好-9

  好了,现在在她的计算机中,遇到“12”计算机会指挥显示器显示“笨蛋”两个字,遇到“89”才会显示“你好”。那我的计算机要跟suntus的计算机通信,我传过去12(计算机只能存储数字,不能直接存储汉字),本来是想说“你好”,她那里就会显示“笨蛋”。这是个问题。
  现在我这套编码升级了,成为了中国的编码标准,suntus的成了日本的标准,那两国之间计算机通信就会乱套,同一个“12”,在中国这里显示是“你好”,到日本那里就 变成“笨蛋”(甚至是别的什么字符,比如“©¬”什么的),这是个大问题。
  全世界都意识到这个问题了,说现在我们要坐下来商量下,不能你一个标准我一个标准,我们需要把全球所有的字符都集中起来,放到一个编码表中,这样同一个“12”在各国计算机中都可以显示“你好”,世界就和谐了。于是就诞生了Unicode字符编码,规定:

1
2
3
4
5
// Unicode的字符编码表
你-1
好-2
a-3
b-4

(实际编码不是这个的,这里只是为了说明下问题。把英文和中文混合起来也是为了避免ascii编码干扰到这里,你在这里可以先忘记ascii和它的历史了)。
  其实除了把文字符号编码成数字,也可以编码成别的什么,比如长横短横(摩斯编码)、电脉冲(铜轴网线)、不停闪烁的光(海上信号灯)等,都是用一定规则把字符表达出来。


3. 编码解码

  现在我们有个大一统的编码表了,全世界所有你见过的字符啊、符号啊都能在这个表中找到对应的数字,但是出现了另一个问题——怎么把这些数字正确的存放到计算机中?为什么会有这个问题呢,我们来看“你好”对应的Unicode编码是“12”,计算机要存储,需要换成01的二进制位,“1”换成二进制是“1”,2换成二进制是“10”,合在一起就是“110”,这样“你好”存放到计算机中就是“110”,这里的存放是不管放到计算机的磁盘还是内存中,还是通过网线传输,都必须是二进制的位。但如果计算机首先看到的是“110”呢?是该把它看成“1”(1)和“10”(2),还是“11”(3)和“0”(0),还是“110”(6)呢?全世界不能你也解释一套,他也解释一套,这样还是乱的,这就需要制定一个统一的编码解码的规则了,也就是utf-8干的事儿。
  在这里编码是把对应的数字变成二进制,放到计算机中;解码是把二进制恢复成数字,进而根据Unicode码表恢复成变成人类可读的东西。有了统一的编码解码规则,全世界所有的计算机见到“110”都会解释成“1”(1)和“10”(2),进而根据Unicode解释成“你好”,全世界再次和谐。
  除了utf-8,你也听过utf-16, utf-32,都是一些对Unicode换成的数字编码解码的规则。


  好了,字符编码的主要概念就是这些了,还有很多零碎的东西自己遇到再看吧。

参考:

  1. 讲的很好,比较严谨易懂:http://cenalulu.github.io/linux/character-encoding/
  2. python遇到的一些问题,这个以后再说:http://www.cnblogs.com/huxi/articles/1897271.html
  3. python和字符终端遇到的编码问题,讲到了字符终端:http://blog.csdn.net/trochiluses/article/details/16825269
  4. 字符编码: https://zh.wikipedia.org/wiki/%E5%AD%97%E7%AC%A6%E7%BC%96%E7%A0%81
  5. Unicode: https://zh.wikipedia.org/wiki/Unicode