Python实现模拟锟斤拷等各类乱码详解

 更新时间:2023年02月23日 10:24:40   作者:小小明-代码实体  
说到乱码问题就不得不提到锟斤拷,这算是非常常见的一种乱码形式,那么它到底是经过何种错误操作产生的呢?本文我们就来一步步探究

锟拷码和口字码

说到乱码问题就不得不提到锟斤拷,这算是非常常见的一种乱码形式,那么它到底是经过何种错误操作产生的呢?下面我们一步步探究。

看一个基本示例:

"��".encode("u8").decode("gbk")

'锟斤拷'

我们将�字符以UTF-8编码后,以GBK编码解码就可以得到 锟斤拷 的乱码。

那么为什么 锟斤拷 为什么如此常见呢?这是因为大部分编程语言在使用UNICODE系列的编码去解码时,会将不识别的字节编码为0xFFFD(65533)即�字符表示未知字符进行占位:

"\uFFFD"

'�'

注意:UNICODE系列包括UTF-8、UTF-16、UTF-32编码,一般UNICODE编码指UTF-16编码。在python中unicode_escape编码表示UNICODE编码的的转义形式:

"\uFFFD".encode("unicode_escape").decode()
'\\ufffd'

对于Python,默认情况下解码碰到未知字符时会直接抛出异常,但是如果设置errors参数为replace时,则会将未知字符解码为�占位。

将汉字用GBK编码:

"小小明".encode("gbk")

b'\xd0\xa1\xd0\xa1\xc3\xf7'

将上述编码结果用UTF-8编码解码,并设置为替换模式:

"小小明".encode("gbk").decode("u8", "replace")

'СС��'

0xd0a1被解码成С,但是0xc3和0xf7无法被UTF-8编码识别,只能用占位符�替换,于是就得到了上面的结果。

此时我们再编码并解码:

"小小明".encode("gbk").decode("u8", "replace") \
    .encode("u8").decode("gbk", "replace")

'小小锟斤拷'

这是因为�被编码成了0xEFBFBD

"��".encode("u8")

b'\xef\xbf\xbd\xef\xbf\xbd'

而0xEFBFBDEFBFBD被GBK解码时,正好就是锟(0xEFBF),斤(0xBDEF),拷(0xBFBD)。

上述以�为主的乱码字符就是口字码,原因是以UTF-8编码读取了GBK编码的中文。

而锟拷体则是大部分都是锟斤拷的全中文字符,原因是用GBK编码读取了UTF-8编码的口字码中文。

古文码与问句码

问句码产生的核心原因在于GBK对于无法编码的字符会使用?填充:

"�😑".encode("gbk", "replace")

b'??'

古文码则与前面的口字码产生原因相反,使用GBK编码读取以UTF-8编码的中文:

"小小明".encode("u8").decode("gbk", "replace")

'灏忓皬鏄�'

此时的 灏忓皬鏄 就非常像古文,gbk解码对于不识别的字节也使用�占位。

此时gbk编码对于�编码失败,使用?替代:

'灏忓皬鏄�'.encode("gbk", "replace")

b'\xe5\xb0\x8f\xe5\xb0\x8f\xe6\x98?'

此时再用UTF-8解码就得到了问句码:

b'\xe5\xb0\x8f\xe5\xb0\x8f\xe6\x98?'.decode("u8", "ignore")

'小小?'

不过问句码只在原始字符串为奇数时产生,如果原始字符串长度为偶数,使用上述编码方式则可以原样还原字符串:

"小小明月".encode("u8").decode("gbk", "replace") \
    .encode("gbk", "replace").decode("u8", "ignore")

'小小明月'

这样说明只要我们将原始汉字字符串填充到偶数,就可以使用古文码实现可逆的数据传输,而锟拷体则是一种不可逆的乱码。

符号码和拼音码

还有两种可逆的乱码,我们先看看符号码:

"小小明".encode("u8").decode("iso8859-1")

'å°\x8få°\x8fæ\x98\x8e'

像这种大部分字符为各种符号的乱码就称为符号码,符号码可以直接还原为原始的文本:

'å°\x8få°\x8fæ\x98\x8e'.encode("iso8859-1").decode("u8")

'小小明'

再看看拼音码:

"小小明".encode("gbk").decode("iso8859-1")

'ССÃ÷'

这种大部分字符都是带有声调的字母称为拼音码,同样可以直接还原:

'ССÃ÷'.encode("iso8859-1").decode("gbk")

'小小明'

总结

名称示例特点原因
口字码СС��大部分字符是问号小方块UTF-8解码GBK编码的中文
锟拷体锟斤拷小小锟斤拷学习锟斤拷全中文字符,大部分都是"锟斤拷"这几个字符GBK解码UTF-8编码的口字码
古文码灏忓皬鏄庢湀大部分都是生僻字,像古文GBK解码UTF-8编码的中文汉字
问句码小小?字符串长度为奇数时,结尾为问号GBK遇到不能编码的字符时填充
符号码好好å\xad¦å¤©å¤©å\xad¦大部分字符为各种符号ISO8859-1编码解码UTF-8编码的中文汉字
拼音码ºÃºÃѧϰÌìÌìÏòÉÏ大部分字符都是带有声调的字母ISO8859-1编码解码GBK编码的中文汉字

到此这篇关于Python实现模拟锟斤拷等各类乱码详解的文章就介绍到这了,更多相关Python模拟乱码内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Python脚本如何在bilibili中查找弹幕发送者

    Python脚本如何在bilibili中查找弹幕发送者

    这篇文章主要介绍了如何在bilibili中查找弹幕发送者,本文给大家分享小编写的一个python脚本来实现bilibili弹幕发送者,需要的朋友可以参考下
    2020-06-06
  • python使用cookie库操保存cookie详解

    python使用cookie库操保存cookie详解

    Python中Cookie模块(python3中为http.cookies)提供了一个类似字典的特殊对象SimpleCookie,其中存储并管理着称为Morsel的cookie值集合,这里介绍了python操作cookie的使用方法
    2014-03-03
  • python中pow函数用法及功能说明

    python中pow函数用法及功能说明

    在本篇文章里小编给大家整理的是一篇关于python中pow函数用法及功能说明内容,有需要的朋友们可以学习下。
    2020-12-12
  • django将网络中的图片,保存成model中的ImageField的实例

    django将网络中的图片,保存成model中的ImageField的实例

    今天小编就为大家分享一篇django将网络中的图片,保存成model中的ImageField的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-08-08
  • python添加模块搜索路径方法

    python添加模块搜索路径方法

    下面小编就为大家带来一篇python添加模块搜索路径方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-09-09
  • django配置连接数据库及原生sql语句的使用方法

    django配置连接数据库及原生sql语句的使用方法

    这篇文章主要给大家介绍了关于django配置连接数据库,以及原生sql语句的使用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-03-03
  • Django 配置多站点多域名的实现步骤

    Django 配置多站点多域名的实现步骤

    这篇文章主要介绍了Django 配置多站点多域名的实现步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-05-05
  • python中enumerate的用法实例解析

    python中enumerate的用法实例解析

    这篇文章主要介绍了python中enumerate的用法,对Python初学者而言是非常重要的概念,需要的朋友可以参考下
    2014-08-08
  • pandas读取csv文件提示不存在的解决方法及原因分析

    pandas读取csv文件提示不存在的解决方法及原因分析

    这篇文章主要介绍了pandas读取csv文件提示不存在的解决方法及原因分析,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-04-04
  • python实现随机漫步算法

    python实现随机漫步算法

    这篇文章主要为大家详细介绍了python实现随机漫步算法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-08-08

最新评论