乱码(二)再现乱码的四大天王
“屯屯屯”
在VisualC++6.0的环境,打印未初始化的由malloc申请的内存,就会出现这样的乱码。
源码
乱码如下:
全局的屯
其实这种乱码算不得乱码,是程序写错才出现的结果,而且结果明显提示程序错误。
原因是编译器自动把内存的值初始化为"CDCD...",而CDCD的GB2312编码正好是“屯”字。
而且这个错误只在Debug模式出现。切换成为Release模式,就不会出现这样的乱码了,取而代之的是其它形式的乱码。
“烫烫烫”
同样的,打印未初始化的局部内存,则出现“烫烫烫”。
可以让机器喊“烫”的代码
乱码如下:
局部的烫这是因为内存被初始化为"CCCC",而这正是“烫”字的GB2312编码。
也只出现在Debug模式。
“锟斤拷”
想要如实的再现这种乱码,其实不容易。过去常常出现在网页上,不出现则已,一出现就是大面积的出现。有些东西,你想找的时候,却总也找不到。等你不找的时候,它就自动出现了。等我发现哪个网页上出现的时候,截个屏下来,就有了。不过现在很难等到这样的机会。
超市售卖的锟斤拷这个锟斤拷的价格是22.00元每盒,不知道以后会不会涨价。我留个邮箱,请网友把生活中见到的锟斤拷发给我,我准备收集这玩意er。
网友的说法
远古兵器。
传说中的锟斤拷应该是手持兵器,很可能双手持。
此物威力不可小觑,后人也有见过此物真身,但以其破坏力推测大概只是一些普通后代。
据说使用者通常心决简洁,如你所料:烫烫烫。
手持两把锟斤拷,口中疾呼烫烫烫。
我深表赞同。
还有网友分析,产生这种现象的原因是:
该现象产生的原因是多方面的,
一来是Microsoft、Sun等垄断公司对编码问题这种细节做得不够细致,
二来是PM经常克扣程序员工资,导致程序员代码激情和质量下降.
我也深表赞同。但把Sun公司改成Oracle。
用Java可以再现(代码来自网络)
锟斤拷的制造方法
java的源文件是GBK编码的,运行的终端是UTF8编码的,可以看到,GBK并没有被正确的转换成为UTF-8,而这个不正确的UTF-8编码最终被转换成了“锟斤拷”。
这种“不正确”的写法其实源自Perl,Encode模块。用Perl语言的话,大致就是这样写的。凭直觉编程也会这样写。这说明Java做了些画蛇添足的事情。
锟斤拷批量生产java虚拟机中使用unicode编码保存字符,任何编码都提供了和unicode编码的转换规则。
出现“锟斤拷”说明在字节和字符的转换(编码和解码)过程中使用了不同的编码,找出编解码的代码,修改成同一种编码即可。
正确的方式可以看到,正确的方式下,参数“源的编码格式”并没用到,因为Java知道源的格式。
“锘锘锘”
这种乱码的出现,跟BOM有关。UTF-8的BOM是"EF BB BF",“锘”字GB2312编码正好是"EFBB"。所以,一个有BOM的UTF8文件,用不能识别BOM的文本编辑器打开,且当作GBK编码打开,开头必定出现“锘”字。
这种乱码也是上古的兵器。想要再现这个乱码,必须找到一种古老的编辑器或浏览器。UTF8文件的BOM是微软倡导的,微软的Notepad自然能正确识别,所以排除在外。
我用Perl强行插入BOM,然后把终端调节成GBK编码,勉强再现了“锘”字乱码。
生成方法:
插入BOM乱码如下:
锘字乱码
有诗总结
以上四大经典乱码,还有网络配诗:
手持两把锟斤拷
口中疾呼烫烫烫
脚踏千朵屯屯屯
笑看万物锘锘锘
这首诗生动描绘了四种经典的乱码,表现了程序员日常的生活场景。
其中,锟斤拷是乱码四大天王之首。