编码史记

字符编码的故事
字符是什么
字符是什么?就是有意义的图形,比如a,中等。在不同的国家代表不同的意思。

但是在计算机世界中只有0和1,好了,如何用0和1将这些字符表示出来呢?这就是编码存在的意义。

编码一点也不高深,就是一个计算机的01和字符ab的简单映射。

于是故事开始了...
很久很久以前,计算机世界只有美国人。美国人的文字造诣很低的,他们的所有文字就只有24个字母,甚至加上大写和小写,阿拉伯数字,计算机中的控制符(回车啥的)都不超过256个(只有127个)。于是,对于他们来说,很自然,那么计算机中用8位就可以表示他们的所有字符了吧。于是他们将8位称作一个字节,计算机的8位表示的每个数字对应了一个英文字符,画了一张表(ASCII码表)。最早的编码AscII码出现了。

欧洲人出场了。欧洲是有好多个国家的,他们的每个国家也都有自己的文字,比如拉丁文,希腊文等。怎么办呢?于是想到,你美国人指定的ASCII码表里面不是只有127个字符吗,后面128-255的字符不是说待定吗,好吧,我们就不客气了。于是欧洲人就将各种奇怪的语言塞入127后面的字符中,形成了一系列的ISO 8859字符集。比如希腊文塞入ASCII,就形成了ISO/IEC 8859-7,西欧语种塞入ASCII就形成了ISO/IEC 8859-1,ISO/IEC 8859-1也叫做latin-1。(对,就是mysql里面经常见到的编码)

下面是ISO 8859现有的15个字符集

ISO/IEC 8859-1 (Latin-1) - 西欧语言
ISO/IEC 8859-2 (Latin-2) - 中欧语言
ISO/IEC 8859-3 (Latin-3) - 南欧语言。世界语也可用此字符集显示。
ISO/IEC 8859-4 (Latin-4) - 北欧语言
ISO/IEC 8859-5 (Cyrillic) - 斯拉夫语言
ISO/IEC 8859-6 (Arabic) - 阿拉伯语
ISO/IEC 8859-7 (Greek) - 希腊语
ISO/IEC 8859-8 (Hebrew) - 希伯来语(视觉顺序)
ISO 8859-8-I - 希伯来语(逻辑顺序)
ISO/IEC 8859-9(Latin-5 或 Turkish)- 它把Latin-1的冰岛语字母换走,加入土耳其语字母。
ISO/IEC 8859-10(Latin-6 或 Nordic)- 北日耳曼语支,用来代替Latin-4。
ISO/IEC 8859-11 (Thai) - 泰语,从泰国的 TIS620 标准字集演化而来。
ISO/IEC 8859-13(Latin-7 或 Baltic Rim)- 波罗的语族
ISO/IEC 8859-14(Latin-8 或 Celtic)- 凯尔特语族
ISO/IEC 8859-15 (Latin-9) - 西欧语言,加入Latin-1欠缺的芬兰语字母和大写法语重音字母,以及欧元(€)符号。
ISO/IEC 8859-16 (Latin-10) - 东南欧语言。主要供罗马尼亚语使用,并加入欧元符号。

接着伟大的中国人也开始使用上电脑了。中文可不得了,文字博大精深,字符远远超过了256个。所以我们无法使用ASCII的扩展了。怎么办呢? 1981年的时候,国家派一批人来做了这个事情,他们统计出所有的中文大概有6000多个字符(后来证明这些人的水品也是有限,好多字符都没有搜出来,于是就有了多种的中文编码),用两个字节(16bit)来表示,16bit能表示的是65536个字符,太够了。我们将16bit分为前8bit和后8bit
如果前8bit小于127(英文ASCII),那么这个8bit就是表示英文
如果前8bit大于127,那么这8bit和后面的8bit合起来表示一个中文
GB是啥意思?国标。

好了,后来某些领导发现,他的名字没法编码了,这个问题出来了。6000个汉字还不足以囊括所有中文,国家在1995年又组织了一批人,继续搜罗一些生僻字,一共搜集出了21886个汉字和字符,形成了GBK编码,GBK编码向下兼容GB2312。

K是啥意思?扩展。

再后来发现了,一些满文,蒙古文啥的少数名族的语言没有编辑到GBK中,继续编辑收录,形成了GB18030编码。

中国台湾的人民当然不能使用大陆编辑使用的GBXX系列编码了,于是他们自己搞了一套BIG5中文编码,收录了13060个汉字和字符。但是这里要注意,BIG5的编码映射表和GBXX系列的就完全不一样了,比如同一个“中”字,在BIG5和GB2312中就是两个完全不同的字节。这里就会有乱码出现了,比如("陶喆"和"陶吉吉"),各种简体中文和繁体文的转码工具就出现了。
BIG5是什么意思?
五种中文套装软体:文书处理,资料库,试算表,通讯,绘图。大致的意思是这套编码主要使用于这5个领域

各个国家使用各个国家自己的编码有没有很繁琐?于是大家很期盼有一种统一的编码形式出现。Unicode编码出现了。Unicode使用的通用的字符集叫做UCS。这个字符集就是一个大的字符空间,每个语种都在这个字符空间内划分一段领域。现在应用的UCS是UCS-2,意思就是不管是英文中文,统一使用两个字节(16bit)来进行字符分配。UCS-2字符集可以表示216(即65536)个字符。已经基本满足世界上所有语言了。如果不够怎么办?已经有预定方案UCS-4(用4个字节表示一个字符)。

切记:UTFXX是Unicode的具体实现方式。
UTF-16是Unicode最基本的实现。Unicode使用16bit表示一个字符,UTF-16就是直接将字符集的映射搬过来而已。

本来这样就已经很美好了,但是美国人又不干了。凭什么每个英语字符要占用2个字节?凭什么占用了我们的带宽和CPU?于是一帮英语体系的外国人讨论出了UTF-8这种字符编码。
UTF-8这种编码是怎么回事呢?
英文字符,和ASCII码一样,占用一个字节
其他语种,每种语种分配一个模板,这个模板有16bit,24bit,甚至还有32bit的。各个语种根据这个模板,将自己的语言转化成模板要求的编码(UTF-8)

这里演示一个中文字“汉”
比如中文分到的模板是1110xxxx 10yyyyyy 10zzzzzz
汉字的Unicode编码是0x6C49,二进制是0110 1100 0100 1001
将这个二进制按照模板的x,y,z顺序插入
得到11100110 10110001 10001001 就是E6 B1 89

好了…大家看出这个对中文有什么不好的吗?原先一个中文使用UTF-16只需要两个字节,但是使用UTF-8却需要3个字节,如果一个网页有1w个中文字,那么我们就需要多传输1w个字节,带宽啊!! 现在就明白了,为什么国内一些网站,比如sina,它的编码规则是使用GBK了吧!

下面再说一下很多编辑器的自动编码匹配的问题。编辑器会检查出你输入的字符是UTF-8还是GBK,基本根据的就是这个UTF-8模板,如果符合模板,就会判断是UTF-8。很多文章说的txt中输入“联通”存为GBK编码再打开会出现乱码就是这个原因导致的。
具体请看这篇文章

还有一种ANSI是什么呢?windows内核是使用UTF-16编写的,但是页面上展示的语言是根据系统设置的“语言”来展示的。ANSI就是windows系统根据你设置的语言环境而进行自动变化的一种编码。比如在中文windows系统下,ANSI就代表GBK编码,日文操作系统下就代表JIS编码。

参考资料

字符编码详解及由来
字符集和字符编码

(0)

相关推荐

  • 字符集和字符编码(Charset & Encoding)

    相信大家一定碰到过,打开某个网页,却显示一堆像乱码,如"бЇЯАзЪСЯ"."�????????"?还记得HTTP中的Accept-Charset.Accept-Encoding.Accept-Language.Content-Encoding.Content-Language等消息头字段?这些就是接下来我们要探讨的. 目录: 1.基础知识 2.常用字符集和字符编码2.1. ASCII字符集&编码2.2. GBXXXX字符集&编码2.3. BIG5字

  • 字符编码详解及由来(UNICODE,UTF-8,GBK) 比较详细

    很久很久以前,有一群人,他们决定用8个可以开合的晶体管来组合成不同的状态,以表示世界上的万物.他们看到8个开关状态是好的,于是他们把这称为字节. 再后来,他们又做了一些可以处理这些字节的机器,机器开动了,可以用字节来组合出很多状态,状态开始变来变去.他们看到这样是好的,于是它们就这机器称为"计算机". 开始计算机只在美国用.八位的字节一共可以组合出256(2的8次方)种不同的状态. 他们把其中的编号从0开始的32种状态分别规定了特殊的用途,一但终端.打印机遇上约定好的这些字节被传过来时

  • 编码史记

    字符编码的故事 字符是什么 字符是什么?就是有意义的图形,比如a,中等.在不同的国家代表不同的意思. 但是在计算机世界中只有0和1,好了,如何用0和1将这些字符表示出来呢?这就是编码存在的意义. 编码一点也不高深,就是一个计算机的01和字符ab的简单映射. 于是故事开始了... 很久很久以前,计算机世界只有美国人.美国人的文字造诣很低的,他们的所有文字就只有24个字母,甚至加上大写和小写,阿拉伯数字,计算机中的控制符(回车啥的)都不超过256个(只有127个).于是,对于他们来说,很自然,那么计

  • 洗洗睡吧,没什么大不了的(人生励志篇)

    离家几个月不见父母就觉得委屈了? 没好朋友陪你嘻嘻哈哈就寂寞了? 考试论文作业多就娘的受不了的? 忙学习还要想着课外活动觉得忙不过来了? 几个晚上睡不好觉他妈的就没法活了? 觉得前途未卜未来迷茫就痛不欲生了? 就那么点屁大的压力就他妈撑不住了? 人司马迁被阉了还不活着好好的写史记, 人贝多芬聋了还不照样玩音乐, 人刘伟没手不还一样弹钢琴, 人海伦凯勒聋哑盲还一样学知识, 人易帝天天被冒还不照样打NBA, 只要身体都好好的有啥不能克服过去? 压力再大能打过奥巴马? 中期选举败成这样也没见他受不了,

  • 端午节由来的各种不同说法

    端午还有许多别称,如:夏节.浴兰节.女儿节,天中节.地腊.诗人节等等.端午节的别称之多,间接说明了端午节俗起源的歧出.事实也正是这样的.关于端午节的来源,时至今日有很多种说法-- 纪念屈原说 据<史记>"屈原贾生列传"记载,屈原,是春秋时期楚怀王的大臣.他倡导举贤授能,富国强兵,力主联齐抗秦,遭到贵族子兰等人的强烈反对,屈原遭馋去职,被赶出都城,流放到沅.湘流域.他在流放中,写下了忧国忧民的<离骚>.<天问>.<九歌>等不朽诗篇,独具风貌

  • 微信小程序CSS3动画下拉菜单效果

    微信小程序没有自带的下拉菜单组件,因此我们需要自己需要写一个 思路 利用列表来存储菜单项,在外面套一个view元素作为外框,将其设置为overflow:hidden,使用CSS3动画逐渐改变外层view元素的高度,当高度为0时,里面嵌套的列表元素被完全隐藏,相当于菜单关闭.而当view元素的高度大于列表元素的高度时,相当于菜单显示. 效果图 wxml button按钮用于触发菜单的打开和关闭,first_click参数使用户第一次点击按钮之前菜单不可见,state参数用于控制菜单的打开和关闭状态

  • Java中的字符编码问题处理心得总结

    当面对一串字节流的时候,如果不指定它的编码,其实际意义是无法知道的. 这句话应该也是我们面对"字符转字节,字节转字符"问题时候时刻记在脑子里的.否则乱码问题可能就接踵而至. 其实乱码问题的本质就是Encoding和Decoding用的不是一个编码,明白了这个道理就很好解决乱码问题了. Java中常见的时候有如下: 1. String类使用byte[]的构造函数 String(byte[] bytes),String类同时提供了两个重载 (1)String(byte[] bytes, C

  • 基于java Servlet编码/异常处理(详解)

    1. Servlet输出中文 (1)为什么会有乱码? out.println方法在输出时或者表单提交的时候,浏览器会对表单中的中文参数值进行编码; 注:会使用表单所在的页面打开时使用的编码方式进行编码服务器端默认会使用ISO-8859-1进行解码所以会产生乱码 (2)如何解决? 1)post请求:requset.setcharcterencoding(string charset);添加到所有获取参数前并且该方法只支持post方法 2)get请求:修改服务器设置 2. 读取请求参数值 (1)St

  • Python开发编码规范

    这篇文档所给出的编码约定适用于在主要的Python发布版本中组成标准库的Python   代码,请查阅相关的关于在Python的C实现中C代码风格指南的描述. 这篇文档改编自Guido最初的<Python风格指南>一文,并从<Barry's style guide>中添加了部分内容.在有冲突的地方,Guide的风格规则应该是符合本PEP的意图(译注:指当有冲突时,应以Guido风格为准).这篇PEP仍然尚未完成(实际上,它可能永远都不会完成).   在这篇风格指导中的一致性是重要的

  • php5.4以上版本GBK编码下htmlspecialchars输出为空问题解决方法汇总

    从旧版升级到php5.4,恐怕最麻烦的就是htmlspecialchars这个问题了!当然,htmlentities也会受影响,不过,对于中文站来说一般用htmlspecialchars比较常见,htmlentities非常少用到. 可能老外认为网页普遍应该是utf-8编码的,于是苦了那些用GB2312,GBK编码的中文站......! 具体表现: 复制代码 代码如下: $str = "9enjoy.com的php版本是5.2.10"; echo htmlspecialchars($s

  • 程序员趣味读物 谈谈Unicode编码

    问题一: 使用Windows记事本的"另存为",可以在GBK.Unicode.Unicode big endian和UTF-8这几种编码方式间相互转换.同样是txt文件,Windows是怎样识别编码方式的呢? 我很早前就发现Unicode.Unicode big endian和UTF-8编码的txt文件的开头会多出几个字节,分别是FF.FE(Unicode),FE.FF(Unicode big endian),EF.BB.BF(UTF-8).但这些标记是基于什么标准呢? 问题二: 最近

  • PHP UTF8编码内的繁简转换类

    曾找过一个JS版的,但是到了UTF8编码里不能用,于是就产生了自已写一个的念头.其实我这个代码的实现原理很简单的,只是一个替换字符集的过程,相信大部份人都可以写得出来.以下是代码,不知道有没有bug,大家如果在使用上有问题,可以提出来 复制代码 代码如下: <?php //<meta charset=utf-8"> class utf8_chinese { private $utf8_gb2312; private $utf8_big5; public function __c

随机推荐