乱码是个啥
我们说的乱码,大部分其实都是中文乱码。
例如这次我遇到的,“北京” 两个汉字变成了 “鍖椾含”
出现乱码的原因
我们知道,电脑屏幕显示的汉字其实是由一个个像素点构成的。
而一个汉字其实对应一个字符码。
推导一下,每一个字符码对应一种像素点的组合方式。
如下图:
解码与编码
我们可以这样理解,把字符码变成像素点的过程就叫做"解码"
那么反之,像素点变成字符码的过程叫做"编码"
字符集
那么,咱们解码和编码不能瞎搞吧,0x666我解码成"好",过几天我又解码成"你",这样肯定是不行的。
我们需要一个统一的规则,这个规则就是"字符集"
逆向工程
简单思考一下
说了这么多,怎么处理 “北京” -->“鍖椾含” 这种乱码呢?
我们知道,"鍖椾含"肯定是由字符码 解码过来的。
那么我们就来看看究竟是啥样的字符码会被解码成这玩意。
编码
由像素点–>字符码的过程是编码,那我们就来进行编码。
额,问题来了。我们不知道这个字符集,也就是解码编码的规则。
系统字符集
其实,只要查看系统的字符集就可以了。
echo $LANG
我这里系统的字符集是gb2312。
我们开始进行编码,这里我们可以简单使用一下python。
不要害怕,非常简单的一个命令:
print("鍖椾含".encode("gbk"))
哎,有人说,你这里怎么用了gbk,不是gb2312吗?
gbk对gb2312是一种补充。尤其是对生僻字的补充。
这里三个字肯定是生僻字。。
编码出来的结果:
b'\xe5\x8c\x97\xe4\xba\xac'
大胆猜测,大胆试验
b'\xe5\x8c\x97\xe4\xba\xac'
这个究竟是啥?
这个怎么和北京两个字扯上关系?
我们先考虑,字符码是怎么来的?
回到上面,字符码是 像素点编码得到的。
好,那我们开始对"北京" 进行编码。
print("北京".encode("gbk"))
b'\xb1\xb1\xbe\xa9'
两种编码不一致,看来不是gb2312这种规则。
print("北京".encode("utf8"))
b'\xe5\x8c\x97\xe4\xba\xac'
哦,看来问题已经明了了
复盘乱码的原因
北京 ----编码(utf8) ----解码(gbk) ----鍖椾含
解决方法
只要我们编码的时候,按照gbk的方式进行编码,那么再解码肯定就是对的了。
看看官网
我们去log4j2官网看看,我们使用的Appender是Syslog
链接: SyslogAppender.
我们看到,其中有个charset,我们把charset设置成gb2312。
不就可以把“北京”用gb2312方式编码了吗?
log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
<Appenders>
<Syslog name="SYSLOG" facility="LOCAL2" host="xxx.xxx.xxx.xxxx" port="xxx" protocol="UDP" charset="gb2312" />
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{yyyy-MM-dd} [%t] %-5level %logger{36} - %msg%n" />
</Console>
</Appenders>
<Loggers>
<Logger name="com.myApp" level="warn">
<AppenderRef ref="SYSLOG"/>
</Logger>
<root level="error">
<appender-ref ref="Console"/>
</root>
</Loggers>
</Configuration>