跳到主要内容

一文弄懂字符编码,面对乱码不再抓瞎

· 阅读需 4 分钟

我们都知道,计算机起源自美国。那时候的电脑普遍支持 8 bits 运算。因此,128 位以下的数字用作表达英文字母,即 ASCII 码。

后来,计算机卖到了世界各国,混沌之初,一切无序。各国按照各自的语言,在 128 位以上的广阔天地里自由飞翔。

这样就导致了一个问题,美国人发来的英文邮件在西班牙的电脑上有乱码,根本看不懂!

光是想想,每个国家都有自己的小册子,上面记录了 128 位以上的字母(字符)表示,这要求每个计算机都要存储这些小册子,太疯狂了!

历史车轮滚滚向前,Unicode 出场了。它带着将世界上每一个字符都赋予编码的使命来了。

Unicode 的思路是:每一个字母都分配一个抽象的编号,比如'Hello' - U+0048 U+0065 U+006C U+006C U+006F.

好的,现在赋予编号完成了,可是计算机是基于二进制呀,Unicode 如何存储在计算机中呢?

先做一个简单的心算。上面 Hello 的编码,去掉 U+: 00 48 00 65 00 6C 00 6C 00 6F. 每个数字的范围 0-F,二进制需要四位,也就是半个 byte,所以 00 是一个 byte,一个字母 H 是两个 byte!

这时候,美国人跳出来表达了不满:我们的 ASCII 码用的好好的,八位就可以表达所有的字母,现在要我们用 Unicode,每个字母都要用 16 位,那文件大小生生比原来多了两倍!

于是,UTF-8 为了解决上述痛点,依旧将 128 以下的编码用于英文字母,且只用一个字节,只有 128 以上的,才用两个字节存储。这样,对于英语用户之间的文件传递,没有任何影响。

Unicode 只是一个抽象的操作,将任何字符转化为一个 U+字符串。任何计算机上实际显示一个字符串需要一个编码方案的支持。可以想象的 hello 字符串的 unicode 为...,然后某个编码方案 iso-xxx 中找不到这些码,于是显示?或者 �。

最后,作者特别指出一句话:

It does not make sense to have a string without knowing what encoding it uses.

Joel 的文章地址:


The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!) https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-absolutely-positively-must-know-about-unicode-and-character-sets-no-excuses/