我们平时在处理文本文件或者网络请求时,时不时会遇到乱码的情况,这篇文章就带你彻底搞懂编码和乱码

首先,我们要知道,在计算机中,一切都是用0和1来表示的。普通的txt文件、或者客户端发过来的数据等等,这些一切其实都是通过0和1转化而来的。「那它是怎样从0和1转化我们人能看懂的字母或汉字呢?」

ASCII

起初,计算机是由美国人发明的,而且那时候基本就在美国运行,因此,开始只考虑到了美国的需求,0和1只要能转化成英文字母和符号就行了,大概需要128个字符,所以就规定了0和1转化为这128个字符的规则,称作「ASCII编码」

计算机存储的最小单位是byte,而1byte有8个bit位,足够表示128个字符(「第一位用0表示,剩下7位从0-127分别表示128个字符」),因此ASCII编码就规定1byte对应一个英文字符,对应关系如下图:



虽然ASCII编码对于美国来说足够用了,但是其他国家显然是不够的,于是,各个国家就发明了自己的编码方式,比如我们「中国的GBK和GB2312等」。但是各个国家自己的编码也都会兼容ASCII编码(毕竟人家是鼻祖),前面说到ASCII编码的第一位为0,则其他国家自己的编码都会定义第一位为1,这样就能区分当前是ASCII编码还是自己国家的编码。

中国的编码

对于美国而言,一个字节就能表示所有的字符,但是在中国就不行了,光常见的汉字就有好几千个了,还不包括符号,因此,中国首先出现的编码形式是「GB2312」,它使用两个字节来表示,这种编码主要表示的是简体中文,不包括繁体字。

后来在GB2312的基础上,又发明了「GBK」编码(「GB2312表示的字符,用GBK显示完全一样」),增加了一万多个汉字,里面包括繁体字,这就是我们日常使用最常见的国内编码。此编码也是使用两个字节来表示。

在这里提一下,怎么看一个字符使用了几个字节,可以使用文本编辑器,我这里使用的是EmEditor,当然,其他的也行,如果是nodepad++则需要装一个插件查看二进制。

打开EmEditor,双击右下角的编码,选择GB2312


接着输入一个字符,然后再双击右下角的编码,选择二进制(十六进制)视图。


可以看到,使用的是两个字节。这里再提一点,「为啥查看二进制,很多编辑器默认都是显示的是十六进制」?为啥不直接显示二进制,这是因为,一个字节有8个bit位,而一个十六进制数字能表示4个bit位,所以一个字节刚好可以使用两个十六进制来表示,就像上面显示的“B9 FA",两个表示一个字节,既简单又直观,如果直接使用二进制,要显示十六个0或1,眼都要看花掉。

因此,查看字符的二进制数据,最好是通过十六进制来查看。

世界统一编码

世界上有很多国家,每个国家都有自己特有的编码方式,这就导致了编码不统一,容易造成乱码的情况。那有什么方式可以让编码统一起来呢?可以通过「Unicode」

Unicode和其他编码方式不一样,它没有规定字符对应的二进制,也没有规定每个字符占多少个字节,「它只做了一件事,就是给世界上所有的字符分配了一个唯一的数字编号」,就像人的身份证一样,这是唯一的,它的范围从0x000000到0x10FFFF之间(十六进制以0x开头,二进制以0b开头,八进制以0开头),这个编号一般写成十六进制,前面再加上\u。例如”国“的Unicode就是”\u56fd“。

那这些编号怎么对应到二进制呢?可以采用UTF-8或者UTF-16和UTF-32等。我们平时使用的最多的就是「UTF-8」

UTF-8使用的字节跟Unicode编号的大小有关,编号越大,使用的字节越多,字节个数在1-4之间。对于大部分汉字而已,一个中文字符需要三个字节。而且UTF-8兼容ASCII。

乱码

我们平时出现乱码主要有三种情况。

「第一种」:用文本编辑器打开一个文本文件时,显示乱码。

这种情况是因为,我们平时有时候文本编辑器设置了固定UTF-8编码,但是突然打开一个GBK编码个文件,这时候就会出现乱码,里面只有汉字会乱码。

解决方法:只要将编辑器的编码方式设置成对应的即可。

「第二种」:在程序中读取文件,出现乱码。

这种情况是因为,在程序中读取文件一般都会设置编码,有时候省略编码就会读取系统的默认编码,如果设置的编码和文件的编码对应不上就会出现乱码。

解决方法:读取文件时设置的编码和文件编码保持一致。

「第三种」:接收请求数据出现乱码。

网络中传输的数据也都是二进制数据,所以在我们传输数据的时候,发送方指定一种编码将数据转成二进制通过网络传输到接收方,接收方再指定一种编码将二进制数据转成字符数据。如果发送方和接收方指定的编码不一致,则会出现乱码情况。

解决方法:发送方和接收方采用统一编码即可,一般都是采用UTF-8。

注意:不论是字符串转二进制,还是二进制转字符串都需要指定编码,例如Java中字符串的getBytes()方法将字符串转成字节数组,虽然方法可以不传编码格式,但内部会传入系统默认编码Charset.defaultCharset().name()。又比如String(byte bytes[], String charsetName)方法将字节数组转成字符串,也依然需要传入编码格式,如果不传就会采用系统默认编码。


扫一扫,关注我


Java面试系列-线程相关(一)

2020-09-03

Java到底是引用传递还是值传递

2020-08-07

事务:不好意思,你被隔离了!

2020-07-23

spring事务咋和新冠病毒一样,还会传染?

2020-07-05

数据是怎么一步一步到服务器的

2020-06-18

汉字乱码_彻底搞懂这烦人的编码与乱码!相关推荐

  1. 此上下文中不允许函数定义。_彻底搞懂上下文this,轻松应对,一面就过!!!...

    this不仅仅是Javascript的核心内容,也是前端面试的重点,更是在工作中频繁出现的词,那么this是什么?到底this表达了什么?为什么要有this这个词? 彻底搞懂上下文this 1.1 t ...

  2. python协程详解_彻底搞懂python协程-第一篇(关键词1-4)

    任何复杂的概念或系统都不是凭空出现的,我们完全可以找到它的演化历程,寻根究底终会发现,其都是在一系列并不那么复杂的简单组件上发展演化而来! by 落花僧 本文通过一系列关键概念,逐步递进理解协程. 0 ...

  3. $.ligerdialog.open中确定按钮加事件_彻底搞懂JavaScript中的this指向问题

    JavaScript中的this是让很多开发者头疼的地方,而this关键字又是一个非常重要的语法点.毫不夸张地说,不理解它的含义,大部分开发任务都无法完成. 想要理解this,你可以先记住以下两点: ...

  4. factorybean 代理类不能按照类型注入_彻底搞懂依赖注入(一)Bean实例创建过程

    点击上方"Java知音",选择"置顶公众号" 技术文章第一时间送达! 上一章介绍了Bean的加载过程(IOC初始化过程),加载完成后,紧接着就要用到它的依赖注入 ...

  5. python from. import失败_彻底搞懂Python 中的 import 与 from import

    以下文章来源&作者:青南(谢乾坤) 摄影:产品经理:kingname 的第一套乐高 你好,我是谢乾坤,前网易高级数据挖掘工程师.现任微软最有价值专家(Python 方向),有6年 Python ...

  6. 最短路算法的证明_彻底搞懂最短路算法

    只想说:温故而知新,可以为师矣.我大二的<数据结构>是由申老师讲的,那时候不怎么明白,估计太理论化了(ps:或许是因为我睡觉了):今天把老王的2011年课件又看了一遍,给大二的孩子们又讲了 ...

  7. cad布局怎么用_终于搞懂CAD的布局是个什么玩意儿了!原来布局要这样用

    很多初学的小伙伴都没搞懂CAD布局是怎么一回事儿,其实也没你想像的那么难.今天小编就来跟大家说一说,关于如何新建布局和比例设置等内容,希望对大家有所帮助. 一.布局视口如何定义 1.命令 模型定义布局 ...

  8. 苹果电脑删除软件_软件自动开启很烦人?如何彻底关掉开机自动开启的应用程序...

    使用Mac的小伙伴有没有这样的烦恼,电脑一开机,一堆烦人的软件就自动开启了,让人很懊恼,如何才能彻底关掉开机自动开启的应用程序?mac开机启动项怎么设置?开机启动项要怎么禁止?今天就带大家解决这个懊恼 ...

  9. 怎么关闭电脑开机自动启动的程序_软件自动开启很烦人?如何彻底关掉Mac电脑开机自动开启的应用程序?...

    使用Mac电脑的小伙伴有没有这样的烦恼,电脑一开机,一堆烦人的软件就自动开启了. 如何才能彻底关掉开机自动开启的应用程序?mac开机启动项怎么设置?开机启动项要怎么禁止?今天就带大家解决这个懊恼的问题 ...

最新文章

  1. svn import无法上传库文件lib.a
  2. dialogue怎么读_法语助手|法汉-汉法词典 dialogue是什么意思_dialogue的中文解释和发音_dialogue的翻译_dialogue怎么读...
  3. 三星I9100[4.0 固件ROM] [2012.03.15]万众期待的欧版官方4.0.3完美汉化完美教程
  4. django 1.8 官方文档翻译: 3-4-1 基于类的视图
  5. 测试思想-验收测试 关于验收测试
  6. 40美元18分钟训练整个ImageNet!他们说,这个成绩人人可实现
  7. C++ 智能指针shared_ptr、weak_ptr的简单实现
  8. 微博云原生运维如何快速应对热点流量峰值?
  9. kalipython图形界面_Kali入侵入门版笔记!!!
  10. Discuz!ML 3.x任意代码执行漏洞
  11. ajax请求数据 ztree_ztree通过ajax获取json并勾选checkbook
  12. 在人工智能领域创业,需要明确可知的5个基本条件
  13. 多因子模型 —— 因子正交化处理
  14. 使用Goodcrawler爬取700集的柯南
  15. 服务器主机进不去系统,服务器主机进不了系统
  16. 钉钉发布会发了个“ / ”,还说这玩意能替我们上班?
  17. 笔记:蛋白质结构预测在线工具
  18. 02 stata入门【计量经济学及stata应用】
  19. 一文读懂eBPF/XDP
  20. 协处理器CP15操作指令

热门文章

  1. [深度学习]Ubuntu16.04 + GTX 1050 + cuda8.0 + cuDNN5.1 + caffe安装详解
  2. 使用caffe训练faster-rcnn时遇到的问题总结
  3. caffe基础(7): 命令行解析
  4. matlab创建二叉树(二维数据)
  5. Butterknife 的简单使用 和 配合 Butterknife的插件 Zelezny
  6. 用浏览器训练Tensorflow.js模型的18个技巧(上)
  7. [微信小程序直播平台开发]___(一)介绍与流程
  8. SSH(Struts2+Hibernate+Spring)开发策略
  9. 图论讲解(3)——最小生成树(基础)
  10. 法嵌入互操作类型“SHDocVw.ShellWindowsClass”请改用适用的接口-解决方法