小白在刚开始学习编程,经常会遇到一些乱码问题,导致程序无法编译,在这里,对此进行一个了解。

在聊编码集之前,我们先来了解一些名词解释:

  • 字符集:所谓字符编码就是一个系统支持的所有抽象字符的集合,也就是说我们平常使用的文字,标点符号,图形符号等都是字符集。但计算机无法识别这些文字,只能识别二进制的数字系统,所以需要一套规则,将字符转换成为数字系统,这就是字符编码。
  • 编码: 按照某种字符编码规则( GBK, UTF-8 等) 将字符以二进制序列形式存储在计算机中.
  • 解码: 将存储在计算机中的二进制序列数据解析成对应的字符的过程.

上图表示的是程序运行过程中对字符进行编码和解码的过程的.   请注意 unicode 的重要作用( java语言在代码里声明的每一个char、String类型的变量中字符在在JVM的常量池或磁盘文件中,都是以unicode格式存在的.)  为什么呢?这就要从字符集的发展历史说起了.

编码集发展历史: 
1. ASCII编码:

美国国家标准协会ANSI制定了一个标准,规定了常用字符的集合以及每个字符对应的编号,这就是ASCII字符集(Character Set),也称ASCII码。这个编码集如下,只是一个简单的查表的过程。比如我要存 'a'字符,只要在ASCII表中查到它对应的编码97(或二进制  0110 0001 ),再以二进制流写入存储设备即可.

  2。 OEM字符集

请注意: 此时,ASCII码表只用到了一个字节(八位)中的前七位,第八位没有用到(所以它只能表示128个字符,后面128个数字没有用到).  这样混乱就产生,每个人都可以在 128-255这些位置存放到不同的字符,形成了各种不同的字符集,这些字符集统称为OEM字符集,用这些字符集生成的文档就不容易实现互换了.

3. ISO-8859-1 ( Latin-1 )

在这其中 ASCII最优秀的扩展方案就是 ISO-8859-1,通常称为Latin-1的OEM字符集,它包括了足够的附加字符集来写基本的西欧,希腊语等语言。( 我们安装mysql 5时,就可以注意到,它默认安装的就是latin-1 的字符集 ).

4.  ANSI标准

最后,这个人人参与的OEM终于以ANSI标准的形式形成文件。在ANSI标准中,每个人都认同如何使用低端的128个编码,这与ASCII相当一致。不过,根据所在国籍的不同,处理编码128以上的字符有许多不同的方式。这些不同的系统称为代码页。

讲到这里,大家可以注意到,上面我们提到的字符集都是基于单字节编码,也就是说,一个字节翻译成一个字符。这对于拉丁语系国家来说可能没有什么问题,因为他们通过扩展第8个比特,就可以得到256个字符了,足够用了。但是对于亚洲国家来说,256个字符是远远不够用的。因此这些国家的人为了用上电脑,又要保持和ASCII字符集的兼容,就发明了多字节编码方式,相应的字符集就称为多字节字符集。例如中国使用的就是双字节字符集编码(DBCS,Double Byte CharacterSet)

5. 双字节字符集编码(DBCS,Double Byte CharacterSet)

对于多字节字符集,代码页中通常会有很多码表。那么程序怎么知道该使用哪张码表去解码二进制流呢?答案是,根据第一个字节来选择不同的码表进行解析。   比如Windows系统采用936代码页来实现对GBK字符集的编解码。在解析字节流的时候,如果遇到字节的最高位是0的话,那么就使用936代码页中的第1张码表进行解码,这就和单字节字符集的编解码方式一致了(如下图)。

当字节的高位是1的时候,确切的说,当第一个字节位于0x81–0xFE之间时,根据第一个字节不同找到代码页中的相应的码表,例如当第一个字节是0x81,那么对应936中的下面这张码表:按照936代码页的码表,当程序遇到连续字节流0x81 0x40的时候,就会解码为“丂”字符。

6. GB2312与GBK有什么不同。

它们都占两个字节,但GB2312编码组合出7000多个常用简体汉字,还包括数字符号、罗马希腊字母、日文假名等. 但GB2312并没有把所有的码位都用完.

而GBK是GB2312的扩展(K就是扩展的意思). GBK包括了GB2312的所有内容,同时增加了近20000个新的汉字(包括繁体)和符号 。只要求高位大于0x7F,低位可以小于0x7F,认为是中文。

7. Unicode ( 定长 , 通常使用2个字节,有的是4个字节 , 具体如何以几个字节编码由字符编码(utf-8, utf-16决定).

虽然通过使用不同字符集,我们可以在一台机器上查阅不同语言的文档,但是我们仍然无法解决一个问题:在一份文档中显示所有字符( 这就是乱码的由来, 世界上存在着多种编码方式,同一个二进制数字可以被解释成不同的符号。因此,要想打开一个文本文件,就必须知道它的编码方式,否则用错误的编码方式解读,就会出现乱码。) 。为了解决这个问题,我们需要一个全人类达成共识的巨大的字符集,这就是Unicode字符集。

Unicode字符集将所有字符按照使用上的频繁度划分为17个层面(Plane),每个层面上有216=65536个字符码空间。

其中第0个层面BMP,基本涵盖了当今世界用到的所有字符。其他的层面要么是用来表示一些远古时期的文字,要么是留作扩展。我们平常用到的Unicode字符,一般都是位于BMP层面上的。目前Unicode字符集中尚有大量字符空间未使用。

前面谈到的ASCII,GB2312,GBK字符集都限定了最多2个字节来编码所有字符,并且规定了字节序。这样的编码系统通常用简单的查表,也就是通过代码页就可以直接将字符映射为存储设备上的字节流了. 即这些编码的字符集与字符编码方案(码表)是合在一起了,限制了它的扩展能力。

而unicode在设计上考虑到了这一点,将字符集和字符编码方案分离开

注意左边表示每个字符在unicode字符中都能找到唯一确定的编号(unicode编码),但最终如何以字节流编码和反编码的是具体的字符编码( 如 UTF-8, UTF-16等) . 例如同样是对Unicode字符“A”进行编码,UTF-8字符编码得到的字节流是0x41,而UTF-16(大端模式)得到的是0x00 0x41.

概念上要区分开,以前的GB2312,ASCII即是字符编码方式(这决定如何存,如何读取解析),也是字符集( 表示字符与编号的映射关系),而从unicode开始,它只定了字符的集合和编号,具体如何编码由字符编码方案决定(即 utf-8,utf-16等).

8. utf-8   :变长,所以可以节省空间.

utf-8的特点是它是变长存储,所以适用于存储和网络传输,是具体的字符编码方案.

  • 国际标准组织(ISO)制定英文字符使用1个字节,沿用原来的ASCII码
  • 使用1~4个字节表示一个符号,中文存储使用3个字节(ascii码中的内容用1个字节保存\欧洲的字符, 用2个字节保存\东亚的字符用3个字节保存\特殊符号用4个字节)
  • Unicode是内存编码表示方案(规范),而utf-8是如何保存和传输Unicode的方案(实现)

UTF-8的编码规则:

1)对于单字节的UTF-8编码,该字节的最高位为0,其余7位用来对字符进行编码(等同于ASCII码)。

2)对于多字节的UTF-8编码,如果编码包含 n 个字节,那么第一个字节的前 n 位为1,第一个字节的第 n+1 位为0,该字节的剩余各位用来对字符进行编码。在第一个字节之后的所有的字节,都是最高两位为"10",其余6位用来对字符进行编码。

> 优点:虽然内存汇总的数据都是Unicode,但当数据保存到磁盘或者用于网络传输时,使用utf-8会节省更
多的流量和硬盘空间。UTF8编码后的大小是不一定,例如一个英文字母"a" 和一个汉字 "好",编码后占用的空间大小就不样了,前者是一个字节,后者是三个字节!

总结: 通过上面的讲解,现在在回过头去,体会一下最前面的那张程序编解码运行图,大家能看懂它的意思了吗. 

乱码问题及字符编码集(一)相关推荐

  1. Mysql中各种与字符编码集(character_set)有关的变量含义

    mysql涉及到各种字符集,在此做一个总结. 字符集的设置是通过环境变量来设置的,环境变量和linux中的环境变量是一个意思.mysql的环境变量分为两种:session和global.session ...

  2. html实体编码 在线,HTML实体字符编码集(10页)-原创力文档

    \o "HTML实体字符编码集" HTML实体字符编码集 经常我们会使用到一些特殊字符在WEB页面上的引用方式,比如空格我们通常使用" ",其实所有的字符都具有 ...

  3. 查询数据库的字符编码集

    查询数据库的字符编码集 在命令提示符里输入:mysql -uroot -p 之后会提示输入密码,之后输入下面这条命令:查询字符编码 show variables like 'character_set ...

  4. 在servlet中设置的字符编码集为什么还会出现乱码(亲测)

    首先我们拿个简单的登录看一下 代码实例如下: 我们先看一下错误的代码 1.LoginServlet.java import java.io.IOException; import java.io.Pr ...

  5. java utf-8字符表_Java中的ASCII、Unicode和UTF-8字符编码集

    首先讲一下几种字符的编码方式: 1. ASCII码 我们知道,在计算机内部,所有的信息最终都表示为一个二进制的字符串.每一个二进制位(bit)有0和1两种状态,因此八个二进制位就可以组合出256种状态 ...

  6. php 使用css乱码,分享CSS字符编码引起乱码快速解决的方法

    下面小编就为大家带来一篇分享CSS字符编码引起乱码快速解决的方法.小编觉得挺不错的,现在就分享给大家,也给大家做个参考.一起跟随小编过来看看吧 乱码引起的CSS失效原理: 由于一个中文是两个字符组成, ...

  7. idea console中文乱码_Python3的字符编码乱码问题解决思路

    在乱码问题上,Python3相比Python2已经好多了,但在处理外来字符时比如文件或者网站时还是会出现乱码问题. 乱码的原因很多,一个是来源的字符编码在接收时处理不当,编程语言默认的UTF8处理gb ...

  8. 关于oracle导出的dmp导入失败的问题。提示值过大。oracle修改字符编码集。

    问题描述:导出的dmp文件,再次导入其他oracle时,报错某列的值过大.问题在于编码集不匹配的问题.将导出dmp的oracle修改为目标oracle的编码集即可. 查看字符编码: sql>se ...

  9. php 韩文乱码转换,Unicode字符编码之十进制韩文转为字符

    字符串中出现韩文没能正常显示,在网页中显示了这样的十进制字符: 标题-어디부터 어디까지 期望韩文能正常显示出来: 标题-어디부터 어디까지 韩文的unicode范围 韩文字母 (1100–11FF) ...

  10. mysql 导入设置编码_MySQL导入或导出数据库字符编码集设置

    解决方法: 开始-->运行-->cmd -->进入dos命令窗体:(如果命令无法执行,请将mysql的安装路径放到系统变量path的最前面) 1. 数据库表中字段的字符集设置 .sh ...

最新文章

  1. 【深度学习】(3) 全连接层、激活函数
  2. C#复制数组的两种方式,以及效率比较
  3. actframework mysql_问题处理记录
  4. python手机版下载372-Mac下python环境的安装
  5. 人生苦短,请好好珍惜自已的身体
  6. SwiftUI之深入解析@StateObject、@ObservedObject和@EnvironmentObject的联系和区别
  7. C++类的静态成员详解
  8. 深入浅出BI——搭建环境
  9. flash java 通信,Flash到JavaScript的通信实例
  10. 【渝粤教育】 国家开放大学2020年春季 1013金融统计分析 参考试题
  11. Redis的安装配置与使用
  12. 2021徐州市36中学高考成绩查询,关注!徐州四星级高中高考成绩公布!江苏13市高分学霸真颜曝光!...
  13. iPhonexs文件连接服务器,iPhonexs黑屏了教你如何快速解决!
  14. 定义一个基类BaseClass,从它派生出类DerivedClass。BaseClass有成员函数fn1(),fn2(),DerivedClass也有成员函数fn1(),fn2()。
  15. 规格模式(Specification)
  16. hdu_1720 A+B Comeing
  17. Bomblab(ICS课程回课pku)
  18. 全球都在研发的虚拟气候设备,是治愈“失眠”的最优解吗?
  19. 修改ftp服务器地址,ftp服务器的地址修改
  20. NetSuite合作伙伴

热门文章

  1. mysql数据库 存储过程_Mysql数据库-存储过程
  2. Qt登录界面实现以及跳转不同界面
  3. Flink系列:物理分区分组broadcast、global、shuffle、forward、rebalance、rescale理解与实战
  4. 蓝桥杯之单片机学习(十八)——555定时器与频率测量
  5. python实现 stft_python scipy signal.stft用法及代码示例
  6. C# 通过Http获取网页内容
  7. 移动接入身份认证技术
  8. docker服务及镜像开机自动启动
  9. 保证线程安全的三种方式
  10. 【情报分享1234】来自海莲花组织的道歉,然后再给你扔了个恶意文档