小论计算机Encoding

image.png

乱码问题一直是最让人心烦的一类问题,因为不知从何而来,由何而起,只能一处一处的改编码,运气好了就改成功了,运气不好就继续试,有时候明明把所有能改的地方全改成UTF-8了,却仍然无济于事,着实叫人抓狂。这一切都要从1946年的那个春天说起。
在第一计算机台诞生的时候,那个时候还只有0和1,慢慢的,科学家们厌倦了只有0和1的世界,所以他们就聚在一起开了个会,讨论了讨论,决定按特定的方式将人类语言映射到0和1的序列上,于是他们定了个标准,规定大家都这么干,叫美国标准信息码,就是我们熟知的ASCII。可是天真的美帝国主义,以为计算机只会存在于英语世界中,也没想过我们社会主义程序员也能有用上计算机的一天,所以他们的ASCII码里就没有我们中文,但这是后话了,因为还有一拨人比我们先用上计算机——欧洲程序员。因为欧洲有很多像希腊字母之类的非英文字母,所以他们为了能让整个欧洲正常用上计算机,所以就也弄了一套标准,叫:ISO-xxxx。

ASCII 码使用指定的7 位或8 位二进制数组合来表示128 或256 种可能的字符。标准ASCII 码也叫基础ASCII码,使用7 位二进制数(剩下的1位二进制为0)来表示所有的大写和小写字母,数字0 到9、标点符号, 以及在美式英语中使用的特殊控制字符。其中:

ISO 8859-1编码启用了从128到255的字符,被称为”扩展字符集”。属于单字节编码,应用于拉丁文系列。显然,ISO 8859-1最多能表示的字符范围是0-255(编码范围是0x00-0xFF),其中0x00-0x7F之间完全和ASCII一致,因此向下兼容ASCII。除ASCII收录的字符外,ISO-8859-1收录的字符还包括西欧语言、希腊语、泰语、阿拉伯语、希伯来语对应的文字符号。欧元符号等出现的比较晚,没有被收录在ISO 8859-1当中。

后来随着计算机在世界的普及度越来越高,越来越多地区的人们想要用自己的语言使用计算机,所以就诞生了各种各样的编码方式,其中就包括我们中国的GB系列国家标准信息交换码。

GB系列编码定义了中文汉字、标点的编码。按照GB系列编码,在一段文本中,如果一个字节是0~127,那么这个字节的含义同ASCII编码,否则,这个字节和下一个字节共同组成汉字(或是GB编码定义的其他字符)。因此,GB系列编码向下兼容ASCII,也就是说,如果一段用GB编码文本里的所有字符都在ASCII中有定义,那么这段编码和ASCII编码完全一样。GB编码早期收录的汉字不足一万个,基本满足日常使用需求,但不包含一些生僻的字,后来在一个个新版本中加进去。最早的GB编码是GB2312,后来有GBK,最新的是GB18030,加入了一些国内少数民族的文字,一些生僻字被编到4个字节,每扩展一次都完全保留之前版本的编码,所以每个新版本都向下兼容。

此时,终于有有识之士意识到了混乱的编码给人们网上冲浪带来的不便以及程序bug,所以就有人想用一种编码表示全世界所有的文字,然后就有了Unicode。

Unicode是Unicode.org制定的编码标准,目前得到了绝大部分操作系统和编程语言的支持。Unicode.org官方对Unicode的定义是:Unicode provides a unique number for every character。可见,Unicode所做的是为每个字符定义了一个相应的数字表示。比如,"a"的Unicode值是0x0061,“一”的Unicde值是0x4E00,这是最简单的情况,每个字符用2个字节表示。
Unicode是最统一的编码,可以用来表示所有语言的字符,而且是定长双字节(如果考虑辅助平面,也有四字节的)编码,包括英文字母在内,都以双字节表示,所以它是不兼容ISO 8859-1编码的。不过,相对于ISO 8859-1中所编码的字符来说,Unicode编码只是在前面增加了一个全0字节,例如字母a的Unicode编码为"00 61"。和GB2312/GBK等非定长编码相比,定长编码便于计算机处理,而Unicode又可以用来表示所有字符,所以在很多软件内部是使用Unicode编码来处理的,比如java。
Unicode的编码空间从U+0000到U+10FFFF,共有1,112,064个码位(code point)可用来映射字符. Unicode的编码空间可以划分为17个平面(plane),每个平面包含216(65,536)个码位。17个平面的码位可表示为从U+xx0000到U+xxFFFF, 其中xx表示十六进制值从00(16) 到10(16),共计17个平面。第一个平面称为基本多语言平面(Basic Multilingual Plane, BMP),或称第零平面(Plane 0),码位从U+0000至U+FFFF,包含了最常用的字符。其他平面称为辅助平面(Supplementary Planes)。
对于在Unicode基本多语言平面定义的字符(无论是拉丁字母、汉字或其他文字或符号),一律使用2字节储存,但是从U+D800到U+DFFF之间的码位区段是永久保留不映射到任何Unicode字符的。而在辅助平面定义的字符,即从U+010000到U+10FFFF的码位,则(UTF-16的做法是)以代理对(surrogate pair)的形式,将其拆分成两个2字节(位于0xD800-0xDFFF区段)共4字节的值来储存。进行代理对映射的方法本文就不深入讨论了,有兴趣的可以自行搜索。

但是Unicode占用空间确实有点大,比如说每个英文字符要占用两个字节,但第一个字节其实全部都是零,所以大家就又对Unicode继续编码,然后UTF系列编码方式就诞生了,常见的有utf-8、utf-16等。

UTF-8以字节为单位对Unicode进行编码。从Unicode到UTF-8的编码方式如下:
Unicode编码(十六进制) 
UTF-8 字节流(二进制)
000000-00007F
0xxxxxxx
000080-0007FF
110xxxxx 10xxxxxx
000800-00FFFF
1110xxxx 10xxxxxx 10xxxxxx
010000-1FFFFF 11110xxx10xxxxxx10xxxxxx10xxxxxx
UTF-8的特点是对不同范围的字符使用不同长度的编码。对于0x00-0x7F之间的字符,UTF-8编码与ASCII编码完全相同。UTF-8编码的最大长度是6个字节。从上表可以看出,6字节模板有31个x,即可以容纳31位二进制数字。Unicode的最大码位0x7FFFFFFF也只有31位。

UTF-16编码以16位无符号整数为单位。我们把Unicode

unicode

编码记作U。编码规则如下:
如果U<0x10000,U的UTF-16编码就是U对应的16位无符号整数(为书写简便,下文将16位无符号整数记作WORD)。
如果U≥0x10000,我们先计算U'=U-0x10000,然后将U'写成二进制形式:yyyy yyyy yyxx xxxx xxxx,U的UTF-16编码(二进制)就是:110110yyyyyyyyyy 110111xxxxxxxxxx。

随着将来网络带宽和存储容量的提升,大家都无所谓的用上了万国码,可能以后的程序员们就只能在历史书中见到困扰了他们先辈数十年的乱码问题了吧。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,744评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,505评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,105评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,242评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,269评论 6 389
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,215评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,096评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,939评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,354评论 1 311
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,573评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,745评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,448评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,048评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,683评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,838评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,776评论 2 369
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,652评论 2 354