前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >老是遇到乱码问题:它是如何产生的,又如何解决呢?

老是遇到乱码问题:它是如何产生的,又如何解决呢?

作者头像
捡田螺的小男孩
发布于 2020-04-15 10:39:35
发布于 2020-04-15 10:39:35
1.1K00
代码可运行
举报
运行总次数:0
代码可运行

前言

中文乱码问题在我们日常开发中司空见惯,那么乱码问题是如何产生的呢?又怎样去解决乱码问题呢?本文将结合基本概念和例子展开阐述,希望大家有收获。

一个简单乱码的例子

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package whx;
 


 
import java.io.UnsupportedEncodingException;
 


 
public class TestEncodeAndDecode {
 
 public static void main(String[] args) throws UnsupportedEncodingException {
 


 
 String str = "测试中文乱码";
 
 byte[] b = str.getBytes("GBK");
 
 System.out.println(new String (b,"UTF-8"));
 
 }
 
}
 

用GBK编码,用utf-8解码,产生乱码,运行结果如下:

相关基础概念

要理解乱码的根源,需要先了解清楚位、字节、字符、字符集等相关概念。

位(bit)

位是计算机存储数据的最小单位,1或者0就表示1位,如10010010就表示8位的二进制数。

字节

字节是计算机信息技术用于计量存储容量的一种计量单位,作为一个单位来处理的一个二进制数字串,是构成信息的一个小单位。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1 B = 8 bit (1字节等于8)
 
1 KB = 1024 B = 1024 字节
 
1 MB = 1024 KB
 
1 GB = 1024 MB
 
1 TB = 1024 GB
 
字符

字符是指计算机中使用的字母、数字、字和符号,是数据结构中最小的数据存取单位。如a、A、B、b、大、+、*、%等都表示一个字符;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
ASCII 编码中,一个英文字母字符存储需要1个字节。
 
在 GB 2312 编码或 GBK编码中,一个汉字字符存储需要2个字节。
 
在UTF-8编码中,一个英文字母字符存储需要1个字节,一个汉字字符储存需要34个字节。
 
在UTF-16编码中,一个英文字母字符或一个汉字字符存储都需要2个字节
 
在UTF-32编码中,世界上任何字符的存储都需要4个字节
 
字符集

字符集是多个字符的集合,字符集种类较多,每个字符集包含的字符个数不同。常见字符集名称:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
ASCII字符集
 
GB2312字符集
 
Unicode字符集
 
编码、解码

计算机只认识二进制的1和0,而人类都是有自己的语言的,双方要能进行信息交流,必须要有从文字到0、1的转化,以及0、1到文字转化。

编码:就是将文本字符转换成计算机可以识别的0、1机器码。

解码: 将存储在计算机中的二进制数解析成文字、字符。

常见字符集及其编码方式

常见字符集有ASCII、GBK、Unicode等

ASCII字符集

ASCII字符集:它包括英文字母、阿拉伯数字和西文符号等可显示字符,以及回车键、退格等控制字符。

ASCII 编码:它是美国制定的字符编码,用于将英语字符转化为二进制,规定了128个字符的编码。

GBXXXX字符集

GBXXXX系列包括GB2312、GBK、GB18030,适用于汉字处理、汉字通信等系统之间的信息交换。

GB2312

  • 全称是《信息交换用汉字编码字符集》,支持六千多汉字。
  • 国家简体中文字符集,兼容ASCII,中国大陆和新加坡都采用此编码。
  • 每个汉字及符号以两个字节来表示。
  • 高字节从A1~F7, 低字节从A1~FE。将高字节和低字节分别加上0XA0即可得到编码。

GBK

  • GBK全称《汉字内码扩展规范》,扩展了GB2312,加入对繁体字的支持,支持两万多汉字。
  • 每个汉字及符号也是以两个字节来表示。
  • 高字节从81~FE,低字节从40~FE。

GB18030

  • GB 18030,全称《信息技术 中文编码字符集》,与GB2312、GBK编码兼容,可支持27484个文字
  • 采用变长多字节编码,每个字可以由1个、2个或4个字节组成。
  • 1字节从00~7F; 2字节高字节从81~FE,低字节从40到7E和80到FE;4字节第一三字节从81~FE,第二四字节从30~39。
Unicode 字符集

Unicode是国际组织制定的可以容纳世界上所有文字和符号的字符编码方案。UNICODE字符集有多种编码方式,分别是UTF-8,UTF-16和UTF-32。

UTF-8

  • 是针对Unicode的一种可变长度字符编码。
  • 它可以用来表示Unicode标准中的任何字符,而且其编码中的第一个字节仍与ASCII相容,使得原来处理ASCII字符的软件无须或只进行少部份修改后,便可继续使用。
  • UTF-8使用1~4字节为每个字符编码(ASCIl字符只需1字节编码, 拉丁文、希腊文等需要两个字节编码, 中日韩文字使用三字节编码, 其他极少使用的语言字符使用4字节编码号)

UTF-16

  • 把Unicode字符集的抽象码位映射为16位长的整数(即码元)的序列,用于数据存储或传递。
  • UTF-16比起UTF-8,好处在于大部分字符都以固定长度的字节 (2字节) 储存,但UTF-16却无法兼容于ASCII编码。

UTF-32

  • 一种将Unicode字符编码的协定,对每一个Unicode码位使用恰好32位元,其它的 Unicode 编码方式则使用不定长度编码。
  • 采用4字节编码,处理速度比较快,但是浪费空间,传输速度慢。

一个例子理解编码解码的庐山面目

我们敲代码的程序员,接触最多的就是“hello word”。计算机只认识0和1,它是怎么展示hello word的呢?

上一小节,我们已经知道编码、字符集的知识。我们可以用ASCII编码,把“hello word”翻译成计算机认识的0、1。有兴趣的朋友可以去查一下ASCII对照表

计算机存储的是hello world的0、1二进制码,先将二进制码解码成对应的字符,然后在屏幕上渲染出来,我们看到的就是hello world了

乱码如何产生的呢?

乱码产生的原因主要有两个,一是文本字符编码过程与解码过程使用了不同的编码方式,二是使用了缺少某种字体库的字符集引起的乱码

编码与解码使用了不同的编码方式

例子中,用了utf-8编码,使用了GBK解码,结果产生了乱码。因为在utf-8中,一个汉字用三个字节编码,而GBK中,每个汉字用两个字节表示,所以产生了乱码。

使用了缺少某种字体库的字符集

我们知道GB2312是不支持繁体字的,所以使用缺少某种字体库的字符集编码,会产生乱码。

乱码又如何解决呢

使用支持要展示字体的字符集编码,并且编解码使用同一种编码方式,就可以解决乱码问题了。

接下来列举一下乱码的经典场景与解决方案

IntelliJ Idea乱码问题

IDE项目中的中文乱码问题?File->settings->Editor->File Encodings,设置一下编码方式utf-8

IDE控制台中文乱码?尝试一下这种方式,打开IDE安装目录,找到

在文本末尾添加-Dfile.encoding=UTF-8

数据库乱码问题

查看数据库编码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
show variables like 'character_set%'
 

设置session、global范围的编码方式

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//session 范围
 
set character_set_server=utf8;
 
set character_set_database=utf8;
 
//global 范围
 
set global character_set_database=utf8;
 
set global character_set_server=utf8;
 

session、global范围编码,重启mysql可能编码又变回去了,可以尝试另外一种方式。在mysql(windows环境)的my.ini配置文件中修改或添加下列内容

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[mysql]
 
default-character-set=utf8
 
[mysqld]
 
default-character-set=utf8
 
[client]
 
default-character-set=utf8
 
编码角度的乱码问题

写代码的时候出现中文乱码?追踪定位到编码解码的地方,设置用同一种编码方式。

参考与感谢

  • 从原理上搞定编码(一)-- 初识编码
  • 解决mysql中文乱码问题?

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-01-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 捡田螺的小男孩 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
《面试季》高频面试题-编码,乱码知识
  在编码的江湖中,"乱码"算得上我们遇到的最难缠的"敌人"之一,一旦遇上、轻则心情烦躁、重则心态崩溃。文章开头,让我们再次重温与"乱码"初见面的名场面。
IT学习日记
2022/09/13
6000
《面试季》高频面试题-编码,乱码知识
常见字符集&乱码问题
位数:ASCII是用7位表示的,能表示128个字符;其扩展使用8位表示,表示256个字符。
全栈程序员站长
2022/09/05
6910
为什么不建议在MySQL中使用 utf8 ?
MySQL 字符编码集中有两套 UTF-8 编码实现:utf8 和 utf8mb4。
Guide哥
2021/10/21
1.2K0
Web开发中的中文乱码问题
本文主要是围绕Web开发中涉及到的中文编码这一常见问题展开,包括了对字符编码基础理论的简述以及常见几种编码标准的介绍。其中包括:ASCII、ISO8859-1、Unicode、GBK。下面先对这些字符编码集进行简单的介绍。
topgunviper
2022/05/12
2K0
关于字符编码的那些事
一、编码是什么 编码为了某种目的把信息从一种形式集合转换为另一种形式集合的过程,古时的鸣金收兵,从某种意义上讲也是一种编码,将帅发出了退兵的命令,为了让更多的人能够知道这个命令,传令兵把这个信息转换为了锣声,传递了出去 与编码相对的还有解码,解码是根据某种规则将信息恢复到原状的过程,士兵之前都接收过训练,在听到锣声之后,明白到锣声代表退兵,便开始执行这一命令。 旗语,电报中的莫斯电码等等,这些东西里面也包含了编码 二、关于字符集和字符编码 因为计算机中的信息都是用二进制数表示的,所以我们必须将汉字、英文按照
magicsoar
2018/02/06
1K0
关于字符编码的那些事
问题分析:什么导致mysql乱码?
之前出现过一些因为mysql编码使用不正确,导致出现页面乱码的bug,比如utf8不支持Emoji表情等等。这里对乱码问题做下分析,沉淀下来避免再次出现
王昂
2019/11/16
2.2K0
问题分析:什么导致mysql乱码?
精述字符编码
带你了解ASCII,Latin1,ANSI,Unicode,UCS-2,UCS-4,UTF-8,UTF-16,UTF-32,GB2312,GB13000,GBK,GB18030,BIG5,BMP,Code Page,BOM,MBCS,Little Endian,Big Endian,内码,外码。
恋喵大鲤鱼
2018/08/03
1.5K0
精述字符编码
android 中国通信乱码问题
计算机要处理各种字符,就须要将字符和二进制内码相应起来,这样的相应关系就是字符编码。
全栈程序员站长
2022/07/05
8230
一篇文章帮你解决中文乱码问题---JavaWeb中文编码问题全面解析
这就是为什么我们在浏览器的地址栏中能看到中文,但是把地址拷贝出来后中文就变成了一些奇怪的串了。
谭庆波
2018/08/10
4.8K0
一篇文章帮你解决中文乱码问题---JavaWeb中文编码问题全面解析
【字符编码那些事】ASCII、GB2312、GBK、UTF-8编码以及Unicode字符集
我们在开发中是不是经常会遇到这样的问题,比如你在VS2019中创建了一个工程,里面有C语言程序和中文注释,有一天,根据工作需要,你要把其中的一部分C文件和H文件移植到Keil工程中,当你通过复制黏贴把相应文件移植到Keil工程中,并使用MDK打开时,却发现,你移植的文件C语言程序是正常显示的,但是中文却成了一堆乱码,并且一编译各种莫名其妙的报错。这其实就有可能是你的VS2019和Keil使用了不同的编码方式,因为大部分编码兼容ASCII编码,而C语言程序是英文字符,采用了ASCII编码,所以正常显示,而中文编码就不同了,比如内存中同样的0xB0A1,使用不同编码标准去对0xB0A1解码,得到的可能就是不同的汉字。
mindtechnist
2024/08/08
2K0
【字符编码那些事】ASCII、GB2312、GBK、UTF-8编码以及Unicode字符集
字符编码
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://polaris.blog.51cto.com/1146394/377468
拾点阳光
2018/09/28
2.2K0
从Properties乱码来学习编码
最近使用到java中的Properties来获取一些变量信息,但如果变量值中有中文,那么最终录入到内存中的字符将会变乱码,那么是什么原因使得中文变成乱码呢?
zhangheng
2020/09/07
9060
从Properties乱码来学习编码
浅谈MySQL的乱码、字符集和比较规则
在文章开始前,大家可以先考虑几个问题,这样方便更快理解文章的知识点,下面的问题都会在文章中找到答案哦!
IT学习日记
2022/09/13
1.1K0
浅谈MySQL的乱码、字符集和比较规则
计算机基础篇 | 一看就懂的字符集、ASCII、GBK、UTF-8、Unicode、乱码、字符编码问题
做通信的时候,或者使用IO流读写数据的时候脑袋总是晕晕乎乎的。 与计算机打交道久了,不可避免会看到“鬼画符”式的乱码,让人云里雾里的,特别烦人。
烟雨平生
2023/10/20
5.8K0
计算机基础篇 | 一看就懂的字符集、ASCII、GBK、UTF-8、Unicode、乱码、字符编码问题
字符编码那点事:快速理解ASCII、Unicode、GBK和UTF-8
原作者:阮一峰(ruanyifeng.com),现重新整理发布,感谢原作者的无私分享。
JackJiang
2018/08/29
2.3K0
字符集
本文主要讲解字符集和字符编码的一些概念,通常我们所说的字符集其实指的包含了字符编码集+字符编码。但字符集有时候有时候又只是字符编码集的简称,具体语义根据上下文判断理解就行,也不是必须分的很清楚。
@阿诚
2020/09/01
1.8K0
字符集
字符集和字符编码
我们都知道在计算机内部,所有的数据在存储和运算的时候都应该使用二进制进行表示。例如字母,数字等等。通过二进制进行表示,我们可以指定很多规则来表示这些字符,为了避免不一致性,美国国家标准学会(American National Standard Institute , ANSI )制定了 ASCII(American Standard Code for Information Interchange,美国信息交换标准代码)编码。
用户7657330
2020/08/14
1.1K0
建议收藏,彻底搞懂字符编码问题,从此告别中文乱码
字符编码是计算机技术的基石,本文希望帮助大家彻底梳理清楚字符编码问题,不仅知其然,还知其所以然,摆脱被中文乱码支配的感觉。
业余草
2019/12/20
1.5K0
建议收藏,彻底搞懂字符编码问题,从此告别中文乱码
各种字符编码详解
serena
2017/09/19
2.1K0
各种字符编码详解
从"锟斤拷"到字符编码
我们经常看一些谍战剧,谍战剧里敌特、地下党员以及八路军各部间发送情报的时候,一般都是通过电报发送的,电报在传递的过程中,需要发报员用电键发出长短不一的电码,收报员就会听到电报机发出的滴滴滴答答答的声音。其实电报发出的声音都是"滴"和"答"的组合,"答"的声音是"滴"的三倍长。
Java3y
2019/08/29
1.2K0
从"锟斤拷"到字符编码
相关推荐
《面试季》高频面试题-编码,乱码知识
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档