字符编码终结篇

来源:互联网 发布:淘宝给差评被骚扰 编辑:程序博客网 时间:2024/06/05 03:25

最近弄个串口,被字符编码折腾了好久,还不知下手。狠心阅览网页,记下点心得,希望以后不掉坑。大家双十一快乐。

传说,据《圣经·创世记》第11章记载,当时人类联合起来兴建,希望塔顶通天能传扬己名的高塔。为了阻止人类的计划,上帝让人类说不同的语言,使人类相互之间不能沟通,计划因此失败,人类自此各散东西。这就是巴比伦塔问题。人有人言鸟有鸟语,计算机也有一套自己的语言。而字符编码就是这些语言间的桥梁。也因为语言不通出现了无数千奇百怪的乱码。

现在常见的字符编码嘛。如ASCII,ISO8859,GB2312,GBK,BIG5,unicode,UTF8,16,32.各种规定出来都尽量考虑兼容前边的问题,但是终究由于计算机发展的速度惊人,各种bug还是不断出现。此文先写一些基本概念问题。至于诸如联通记事本bug那样的故事看这里

字符编码乱码篇

最初为了用计算机表示字符,美国人用7位保存128个字符,高位为0.后来呢计算机普及到欧洲其他国家,发现有些字符不够用就把128-255也给扩充了,但是呢各国各干各的,所以这段有千奇百怪的好多。最后一统天下出了个iso8859标准。然后呢,计算机来到了中国,汉字怎么表示,这时候就把原来ascii码保留,而两个字节最高位分别为1来区分ascii和汉字,这就是GB2312。再然后呢,发现有些古汉字不够用的,此时就再扩充下,吧第二个字节的高位也可以为0了。这就出来了GBK,当然也包含了台湾的BIG5繁体字。再后来又加了一些日韩字符成了GB10830.

这是在中国的发展,可以看到,主要是由于用到计算机的人越来越多,原本的方案考虑不周。后面还有第三世界呢,还有从右往左写的阿拉伯呢。乱七八糟的,所以索性把人类所有字符统一编个码吧,这就出来了unicode。以前的ascii可以在GBK里正常显示,但是到了这不好说了。unicode只是给字符编个号。比如给全人类编个身份证号码。身份证号唯一性。但是后期怎么辨别这个人,使用学号?姓名?这些东西区分就是另外的问题了。

unicode只是管着怎么编码,唯一确定字符就好。但是在计算机里存不好存储。网上也不好传输。这时候就有了几种具体的编码方式,比如UTF32,用四个字节表示unicode,但是几乎所有字符前16位都是0,这样多浪费空间啊,于是出来了UTF16,UTF16一般用两个字节,极少数也可以用四个字节。这样省了不少空啊。但是网上数据大多是英文啊,你见几个人用汉字编程,还有每次报文中肯定英语多啊,这样岂不是又很多字符高8位为0了。因此就有了后面的UTF8。它呢,可长可短,从1-6个字节都可以,具体规则看下面。它是目前最广泛的。

ASCII GB2312 GBK GB10830四个,前者几乎都是后面的子集。也就是ascii的值不变,在后者也可以识别。但是unicode就不一样了,unicode和GBk转换要查表,不能一一对应的。

unicode和UTF之间有数学运算可以直接转换。不用查表

文字终究枯燥,还是看图吧,各取所需。


看到这有点晕了吧,知道就是这样,看完下边这些,上边就豁然开朗了。

字符(character)那就是表示一定意义的符号了。各种文字和符号的总称,包括各国家文字、标点符号、图形符号、数字等。

字符集Charset):字符集合。是一个系统支持的所有抽象字符的集合。

字符码,字符的编码。

编码的过程是将字符转换成字节流。

解码的过程是将字节流解析为字符。

字符编码,(Character Encoding将字符映射到字节流:是一套法则,该法则对自然语言的字符集合(如字母表或音节表),与其他东西的一个集合(如号码或电脉冲)进行配对。即在符号集合与数字系统之间建立对应关系,人用符号集合(一般是文字)表达信息。而计算机为基础的信息处理系统则是利用元件(硬件)不同状态的组合来存储和处理信息。元件不同状态的组合代表数字系统的数字,因此字符编码就是将符号转换为计算机可以接受的数字系统的数,称为数字代码。

一个字符映射成计算机里比特,需要如下步骤。
1系统需要支持的字符,这些字符的集合被称为字符表(Character repertoire)
2给字符表里的抽象字符编上一个数字,字符集合到整数集合的映射。映射称为编码字符集(CCS:Coded Character Set),unicode属于这一层的概念,跟计算机里的什么进制啊没有任何关系,它是完全数学的抽象的。
3将CCS里字符对应的整数转换成有限长度的比特值,便于以后计算机使用一定长度的二进制形式表示该整数。这个对应关系被称为字符编码表(CEF:Character Encoding Form)UTF-8, UTF-16都属于这层
4对于CEF得到的比特值具体如何在计算机中进行存储,传输。因为存在大端小端的问题,这就会跟具体的操作系统相关了。这种解决方案称为字符编码方案(CES:Character Encoding Scheme)。

一些名词一些小规律

单字节字符集只需要码表,OEM字符集,多字节字符集MBCS,代码页中有多张码表。根据第一字解选码表,如936代码页代表对应着GBK。codepage就是各国的文字编码和Unicode之间的映射表。使unicode兼容以前各国的编码。

GBK区位码加偏移0xa0就是编码值。区代表行,位代表列。

微软用的UTF8中0xE5BE 0x88E5 0xB18C在GBK中为,也就是有些记事本打开乱码如寰堝睂

Emoji就是一种在Unicode位于\u1F601-\u1F64F区段的字符。

向下兼容,即同一个字符在这些方案中总是有相同的编码,后面的标准支持更多的字符。在这些编码中,ascii gb2312 gbk向下兼容的。
UTF后面的8 16 32为码元大小,也就是一次发送几个。Unicode Transformation Format,简称为UTF
Unicode字符集。4字节的数字来表达。每个数字代表唯一的至少在某种语言中使用的符号。
1)对于单字节的符号,字节的第一位设为0,后面7位为这个符号的unicode码。因此对于英语字母,UTF-8编码和ASCII码是相同的。
2)对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的unicode码。

后面就狂上图了。少说话




参考

通俗易懂故事版。

点击打开链接

http://www.imkevinyang.com/2009/02/%E5%AD%97%E7%AC%A6%E7%BC%96%E8%A7%A3%E7%A0%81%E7%9A%84%E6%95%85%E4%BA%8B%EF%BC%88ascii%EF%BC%8Cansi%EF%BC%8Cunicode%EF%BC%8Cutf-8%E5%8C%BA%E5%88%AB%EF%BC%89.html

关于windows加bom


链接:http://www.zhihu.com/question/20167122/answer/20519798

关于几种编码简介

http://blog.xieyc.com/common-code-standard-unicode-utf-iso-8859-1-etc/

http://www.blogjava.net/xcp/archive/2009/10/29/coding2.html


http://www.zhihu.com/question/20650946

http://www.zhihu.com/question/19677619




0 0