乱码问题及字符编码集(一)
小白在刚开始学习编程,经常会遇到一些乱码问题,导致程序无法编译,在这里,对此进行一个了解。
在聊编码集之前,我们先来了解一些名词解释:
- 字符集:所谓字符编码就是一个系统支持的所有抽象字符的集合,也就是说我们平常使用的文字,标点符号,图形符号等都是字符集。但计算机无法识别这些文字,只能识别二进制的数字系统,所以需要一套规则,将字符转换成为数字系统,这就是字符编码。
- 编码: 按照某种字符编码规则( 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" 和一个汉字 "好",编码后占用的空间大小就不样了,前者是一个字节,后者是三个字节!
总结: 通过上面的讲解,现在在回过头去,体会一下最前面的那张程序编解码运行图,大家能看懂它的意思了吗.
乱码问题及字符编码集(一)相关推荐
- Mysql中各种与字符编码集(character_set)有关的变量含义
mysql涉及到各种字符集,在此做一个总结. 字符集的设置是通过环境变量来设置的,环境变量和linux中的环境变量是一个意思.mysql的环境变量分为两种:session和global.session ...
- html实体编码 在线,HTML实体字符编码集(10页)-原创力文档
\o "HTML实体字符编码集" HTML实体字符编码集 经常我们会使用到一些特殊字符在WEB页面上的引用方式,比如空格我们通常使用" ",其实所有的字符都具有 ...
- 查询数据库的字符编码集
查询数据库的字符编码集 在命令提示符里输入:mysql -uroot -p 之后会提示输入密码,之后输入下面这条命令:查询字符编码 show variables like 'character_set ...
- 在servlet中设置的字符编码集为什么还会出现乱码(亲测)
首先我们拿个简单的登录看一下 代码实例如下: 我们先看一下错误的代码 1.LoginServlet.java import java.io.IOException; import java.io.Pr ...
- java utf-8字符表_Java中的ASCII、Unicode和UTF-8字符编码集
首先讲一下几种字符的编码方式: 1. ASCII码 我们知道,在计算机内部,所有的信息最终都表示为一个二进制的字符串.每一个二进制位(bit)有0和1两种状态,因此八个二进制位就可以组合出256种状态 ...
- php 使用css乱码,分享CSS字符编码引起乱码快速解决的方法
下面小编就为大家带来一篇分享CSS字符编码引起乱码快速解决的方法.小编觉得挺不错的,现在就分享给大家,也给大家做个参考.一起跟随小编过来看看吧 乱码引起的CSS失效原理: 由于一个中文是两个字符组成, ...
- idea console中文乱码_Python3的字符编码乱码问题解决思路
在乱码问题上,Python3相比Python2已经好多了,但在处理外来字符时比如文件或者网站时还是会出现乱码问题. 乱码的原因很多,一个是来源的字符编码在接收时处理不当,编程语言默认的UTF8处理gb ...
- 关于oracle导出的dmp导入失败的问题。提示值过大。oracle修改字符编码集。
问题描述:导出的dmp文件,再次导入其他oracle时,报错某列的值过大.问题在于编码集不匹配的问题.将导出dmp的oracle修改为目标oracle的编码集即可. 查看字符编码: sql>se ...
- php 韩文乱码转换,Unicode字符编码之十进制韩文转为字符
字符串中出现韩文没能正常显示,在网页中显示了这样的十进制字符: 标题-어디부터 어디까지 期望韩文能正常显示出来: 标题-어디부터 어디까지 韩文的unicode范围 韩文字母 (1100–11FF) ...
- mysql 导入设置编码_MySQL导入或导出数据库字符编码集设置
解决方法: 开始-->运行-->cmd -->进入dos命令窗体:(如果命令无法执行,请将mysql的安装路径放到系统变量path的最前面) 1. 数据库表中字段的字符集设置 .sh ...
最新文章
- 【深度学习】(3) 全连接层、激活函数
- C#复制数组的两种方式,以及效率比较
- actframework mysql_问题处理记录
- python手机版下载372-Mac下python环境的安装
- 人生苦短,请好好珍惜自已的身体
- SwiftUI之深入解析@StateObject、@ObservedObject和@EnvironmentObject的联系和区别
- C++类的静态成员详解
- 深入浅出BI——搭建环境
- flash java 通信,Flash到JavaScript的通信实例
- 【渝粤教育】 国家开放大学2020年春季 1013金融统计分析 参考试题
- Redis的安装配置与使用
- 2021徐州市36中学高考成绩查询,关注!徐州四星级高中高考成绩公布!江苏13市高分学霸真颜曝光!...
- iPhonexs文件连接服务器,iPhonexs黑屏了教你如何快速解决!
- 定义一个基类BaseClass,从它派生出类DerivedClass。BaseClass有成员函数fn1(),fn2(),DerivedClass也有成员函数fn1(),fn2()。
- 规格模式(Specification)
- hdu_1720 A+B Comeing
- Bomblab(ICS课程回课pku)
- 全球都在研发的虚拟气候设备,是治愈“失眠”的最优解吗?
- 修改ftp服务器地址,ftp服务器的地址修改
- NetSuite合作伙伴
热门文章
- mysql数据库 存储过程_Mysql数据库-存储过程
- Qt登录界面实现以及跳转不同界面
- Flink系列:物理分区分组broadcast、global、shuffle、forward、rebalance、rescale理解与实战
- 蓝桥杯之单片机学习(十八)——555定时器与频率测量
- python实现 stft_python scipy signal.stft用法及代码示例
- C# 通过Http获取网页内容
- 移动接入身份认证技术
- docker服务及镜像开机自动启动
- 保证线程安全的三种方式
- 【情报分享1234】来自海莲花组织的道歉,然后再给你扔了个恶意文档