编码:编码字符集和字符编码

一、乱码


首先,所有信息在计算机上都是以二进制形式存储。而当出现乱码的时候往往是将这些信息以字符的形式表现之后。这是因为用的编码和解码的方式不一样。
举个例子:
当我们将“祝福”输入电脑时。默认是以GB2312作为字符编码进行编码,将汉字编码成二进制存储在电脑中,当我们再次读取时,若采用UTF-8字符编码来解码输出,就会造成乱码。
就像:
当英国人将“祝福”写在纸上时。默认是以英文来编码,将“祝福”的意思编码成bless。当一个法国人读取时,会通过法语来解码这个单词的意思,在法语中,bless就是“受伤”的意思。就会造成理解错误,而当如果法语如果没有这个单词,就会翻译出错,出现乱码。

二、字符集


字符集是一个规则的集合。就比如上述的英语,汉语,法语。
对于一个字符集来说,正确编码转码一个字符需要三个关键元素:字库表(character repertoire)、编码字符集(coded character set)、字符编码(character encoding form)

其中字库表相当于一个所有字符的数据库。编码字符集(编码用的字符集)用来表示一个字符在字库中的位置。字符编码(字符的编码)表示将编码字符集转化为实际存储的数值。

一般来说,会直接将编码字符集的值作为编码后的值直接存储。例如ASCLL中A的位置是65位,编码后的A的数值是0100 0001,即十进制的65转化为二进制。

</br>
看到这里,可能有人会疑惑:既然每个字符都有自己的编号(编码字符集),那直接存储就好了啊,为什么还要字符编码呢?

其实原因也比较好理解,unicode的出现是为了统一字库表,能够涵盖世界上所有的字符,但实际使用过程中会发现真正用的上的字符相对整个字库表来说比例非常低。例如中文地区的程序几乎不会需要日语字符,而一些英语国家甚至简单的ASCII字库表就能满足基本需求。而如果把每个字符都用字库表中的序号来存储的话,每个字符就需要3个字节(这里以Unicode字库为例),这样对于原本用仅占一个字符的ASCII编码的英语地区国家显然是一个额外成本(存储体积是原来的三倍)。算的直接一些,同样一块硬盘,用ASCII可以存1500篇文章,而用3字节Unicode序号存储只能存500篇。于是就出现了UTF-8这样的变长编码。在UTF-8编码中原本只需要一个字节的ASCII字符,仍然只占一个字节。而像中文及日语这样的复杂字符就需要2个到3个字节来存储。

UTF-8和Unicode的关系
看完上面的解释,那么对于UTF-8和Unicode的关系就比较好理解了。unicode就是上面的编码字符集,而utf-8就是字符编码。也可以理解为unicode是字符在字库里的位置,或者unicode代表整个字库。
unicode几乎包括了所有国家的可能出现的所有字符。Unicode的编号从0000开始一直到10FFFF共分为16个Plane,每个Plane中有65536个字符。而UTF-8则只实现了第一个Plane,可见UTF-8虽然是一个当今接受度最广的字符集编码,但是它并没有涵盖整个Unicode的字库,这也造成了它在某些场景下对于特殊字符的处理困难。

UTF-8编码简介
为了更好的理解后面的实际应用,我们这里简单的介绍下UTF-8的编码实现方法。即UTF-8的物理存储和Unicode序号的转换关系。
UTF-8编码为变长编码。最小编码单位(code unit)为一个字节。一个字节的前1-3个bit为描述性部分,后面为实际序号部分。
1、如果一个字节的第一位为0,那么代表当前字符为单字节字符,占用一个字节的空间。0之后的所有部分(7个bit)代表在Unicode中的序号。
2、如果一个字节以110开头,那么代表当前字符为双字节字符,占用2个字节的空间。110之后的所有部分(7个bit)代表在Unicode中的序号。且第二个字节以10开头
3、如果一个字节以1110开头,那么代表当前字符为三字节字符,占用2个字节的空间。110之后的所有部分(7个bit)代表在Unicode中的序号。且第二、第三个字节以10开头
4、如果一个字节以10开头,那么代表当前字节为多字节字符的第二个字节。10之后的所有部分(6个bit)代表在Unicode中的序号。
具体每个字节的特征可见下表,其中x代表序号部分,把各个字节中的所有x部分拼接在一起就组成了在Unicode字库中的序号

UTF编码

例如“汉”字的Unicode编码是6C49。6C49在0800-FFFF之间,所以肯定要用3字节模板了:1110xxxx 10xxxxxx 10xxxxxx。将6C49写成二进制是:0110 110001 001001,用这个比特流依次代替模板中的x,得到:11100110 10110001 10001001,即E6 B1 89。

其中iso 8859-1,gb2312,gbk,gb18030,big5,unicode等都是编码字符集和字符编码一致的字符集,其中,unicode还有好几种字符编码,比如UTF-8,UTF-16等等。

<br />

三、乱码解决


根据上诉内容,可以知道大部分的乱码都是由解码编码不统一引起的(iso8859-1解码中文也会乱码),那我们怎么解决呢?
其实只要分析每个需要解码的过程,一一分析就可以知道了。以web应用为例:
首先在jsp上面有一行不可或缺的代码<%@ page contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
pageEncoding是jsp文件本身的编码
contentType的charset是指服务器发送给客户端时的内容编码

JSP要经过两次的“编码”,第一阶段会用pageEncoding,第二阶段会用utf-8至utf-8,第三阶段就是由Tomcat出来的网页, 用的是contentType。

第一阶段是jsp编译成.java,它会根据pageEncoding的设定读取jsp,结果是由指定的编码方案翻译成统一的UTF-8 JAVA源码(即.java),如果pageEncoding设定错了,或没有设定,出来的就是中文乱码。

第二阶段是由JAVAC的JAVA源码至java byteCode的编译,不论JSP编写时候用的是什么编码方案,经过这个阶段的结果全部是UTF-8的encoding的java源码。

JAVAC用UTF-8的encoding读取java源码,编译成UTF-8 encoding的二进制码(即.class),这是JVM对常数字串在二进制码(java encoding)内表达的规范。

第三阶段是Tomcat(或其的application container)载入和执行阶段二的来的JAVA二进制码,输出的结果,也就是在客户端见到的,这时隐藏在阶段一和阶段二的参数contentType就发挥了功效

参考文献:
Notepad++的多种编码支持
编译.java文件时的编码问题
【笔面试】字符流和字节流的区别以及如何解决乱码问题
jsp中的contentType与pageEncoding的区别和作用
汉字编码转换原理及方法

四、Notepad++


而像Notepad++等软件,有两种功能


Notepad++

以XXX格式编码是改变编码字符集,意味着在电脑中存储的值是不变的
转为XXX格式编码是改变编码格式,意味着都是同一个字符集,改变的是编码方式,比如UTF-8转UTF-16

utf8mb4可以放表情,4个字节
utf8_bin将字符串中的每一个字符用二进制数据存储,区分大小写。

utf8_genera_ci不区分大小写,ci为case insensitive的缩写,即大小写不敏感。

utf8_general_cs区分大小写,cs为case sensitive的缩写,即大小写敏感。

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

推荐阅读更多精彩内容

  • 原文在这里:各种字符集和编码详解 在软件的编码和实现中,我们可能会碰到个 一个比较头疼的问题--编码,不同字符间的...
    舌尖上的大胖阅读 1,787评论 0 2
  • 乱码 乱码是怎么出现的呢?对同一组二进制数据,不同的编码会解析出不同的字符,用对了编码,解析出来的字符组成的文字是...
    __Jasmine__阅读 606评论 0 0
  • 0 前言 在平时的开发过程中大部分人应该都遇到过中文乱码问题,浏览网页时也会遇到内容显示乱码的情况,一般遇到这种情...
    小猪啊呜阅读 2,557评论 1 10
  • ——“极简主义生活是近年来的流行新趋势,是对自由的重新定义。它强调相对于“物”而言,生活方式应当由“人”所主导。”...
    暮依阅读 1,253评论 0 0
  • 北京街上的女孩同贵阳街上的女孩穿着一样的衣服,讨论着一样的减肥话题。追捧一样的包包,看一样的韩剧。上海的青年同...
    量子时空阅读 657评论 0 0