计算机系统中对数据的编码(GBK,UTF-8,unicode等)
我们平时开发过程中,常常会遇到编码的问题,同一个二进制字节数据,使用不同的编码方式进行编码,显示给我们的结果是不同的。虽然底层的二进制字节数据不变,但是我们使用不同的编码方式加工他们,得到的是不一样的显示字符。
因为不同编码方式的存在,常常使我们遇到因编码方式而产生的不同问题,比如我们常说的乱码问题。
比如我们使用文字处理软件打开一个文件时,我们选择打开它的编码方式不同,往往得到的显示结果不同
本文对编码问题进行一些原理方面的说明,以及平时遇到的问题的解决过程。因时间有限,不能一次性写完,该文章会持续更新
1 编码的本质
2 常见编码
2.1 Base64
Base64使用的64个字符是:
- ABCDEFGHIJKLMNOPQRSTUVWXYZ // 26个大写字母
- abcdefghijklmnopqrstuvwxyz // 26个小写字母
- 0123456789 // 10个数字
- +/ // 2个特殊符号
- 另外还有 = 作为填充字符(不属于那64个字符,是额外用途)
工作原理:
- 原始数据(二进制、文本等)按 每3个字节(24位) 分组
- 24位 重新分成 4组,每组6位
- 6位 可以表示 0-63(2⁶=64种可能)
- 每个6位值对应 Base64 字符表中的一个字符
比如:
原始: [字节1][字节2][字节3]
(8位) (8位) (8位) = 24位
Base64:[字符1][字符2][字符3][字符4]
(6位) (6位) (6位) (6位) = 24位
核心特性:Base64编码是双向的、确定性的、无损失的。给定任意输入,都有一个唯一对应的Base64输出;给定一个合法的Base64字符串,也能唯一准确地解码回原始的二进制数据
3 遇到的问题解决
3.1 编码方式的不同引起的http报文乱码
问题:在windows电脑上,发送curl请求时,在命令行显示的报文无乱码,但是,服务端接口接收到的报文是乱码
客户端:

服务端:
全局Exception e: org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Invalid UTF-8 start byte 0xb1;
定位思路:
出现了乱码,无非两种情况
- 客户端发送的时候就已经乱码了
- 服务端接收时,使用了错误的编码方式
我首先尝试将服务端编码方式设置为默认UTF-8,比如添加filter,设置request的请求头中的编码方式为utf-8.经过尝试,问题还在,因此怀疑是否在发送来的时候就已经是乱码了
然后,想办法在客户端查看发出的报文是什么样的。想到了使用wireshark抓包的方式
第一步,监听localhost网卡

第二步,发起http请求
第三步,查看wireshark抓包结果

我们打开如下界面,看到,中文都变成了".",但是,先别慌,我们看右下方,它的默认编码方式是ASCII码

我们将默认编码方式改为utf-8,我们可以看到,中文出现了乱码。在服务端,我们也是使用utf-8进行解析字节数据,也就是说理论上我们现在看到的也就是服务端看到的,在这里,问题基本找到了,即发送时数据就不对。

我们再使用GBK编码方式查看,发现中文不乱码了,可以证实,客户端软件解析数据时使用了GBK编码,也就是我们再命令行看到的信息,此时,即使我们设置请求方式为utf-8方式,也无效了,因为本质上,发送的二进制字节数据出错了,即使使用utf-8方式发送(Content-Type: application/json; charset=utf-8),发送的二进制数据已经和我们想的不一样了。

解决方式,修改命令行工具的编码方式,我使用的是git bash,暂时不知道如何设置其编码方式。然后,我使用windows中安装的wsl尝试,问题解决了
浙公网安备 33010602011771号