python版本坑:md5例子(python2与python3中md5区别)


Posted in Python onJune 20, 2017

起步

对于一些字符,python2和python3的md5加密出来是不一样的.

# python2.7
pwd = "xxx" + chr(163) + "fj"
checkcode = hashlib.md5(pwd).hexdigest()
print checkcode # ea25a328180680aab82b2ef8c456b4ce

# python3.6
pwd = "xxx" + chr(163) + "fj"
checkcode = hashlib.md5(pwd.encode("utf-8")).hexdigest()
print(checkcode) # b517e074034d1913b706829a1b9d1b67

按代码差异来将,就是在python3中需要对字符串进行 encode 操作,如果没有则会报错:

checkcode = hashlib.md5(pwd).hexdigest()
TypeError: Unicode-objects must be encoded before hashing

这是因为加密时需要将字符串转化为 bytes 类型,3默认编码是 utf-8 .所以我用utf-8进行解码.

分析

如果字符串中没有 chr(163) ,那么两个版本结果是一致的,也就是说问题出在这个chr(163)中:

# python2.7
>>> chr(163)
'\xa3'

# python3.6
>>> chr(163)
'\xa3'

在这里说明通过 chr 得到的结果是一致的, 将它转为 bytes 类型看看:

# python2.7
>>> bytes(chr(163))
'\xa3'

# python3.6
>>> chr(163).encode()
b'\xc2\xa3'

python3中,在 num<128 的时候,使用 chr(num).encode('utf-8') 得到的是 一个 字符的ascii十六进制,而 num>128 的时候,使用 chr(num).encode('utf-8') 得到的是 两个 字节的ascii十六进制.

解决
改用 latin1 编码进行解码:

# python3.6
pwd = "xxx" + chr(163) + "fj"
checkcode = hashlib.md5(pwd.encode("latin1")).hexdigest()
print(checkcode)  # ea25a328180680aab82b2ef8c456b4ce

额外
为什么是 latin1 编码呢.答案还是挺有意思的.

先说chr函数,通过 help(chr) 可以查看:

chr(...)
  chr(i) -> Unicode character
  Return a Unicode string of one character with ordinal i; 0 <= i <= 0x10ffff.

意思是它返回Unicode编码中指定位置的一个字符.python3内部也是用Unicode表示左右字符,即str类型.而通过encode后会编码成 bytes 类型.

ascii编码中每个字符编码是一个byte,但只有1-127. 超过的部分128-255则属于 Extended ASCII ,python3 中默认的ascii中不包含这部分,所以如果执行 chr(163).encode("ascii") 就会报错 'ascii' codec can't encode character '\xa3' in position 3: ordinal not in range(128)

因此需要一个含有128-255中的部分字符的编码,且采用1个Byte固定大小编码,比如ISO 8859-1,也就是 latin1.当然还有其他编码如cp1252也包含这些字符的.

Python 相关文章推荐
Python 的 with 语句详解
Jun 13 Python
python win32 简单操作方法
May 25 Python
python单例模式实例解析
Aug 28 Python
浅析Python 3 字符串中的 STR 和 Bytes 有什么区别
Oct 14 Python
浅谈python中str字符串和unicode对象字符串的拼接问题
Dec 04 Python
python进程和线程用法知识点总结
May 28 Python
如何用Python制作微信好友个性签名词云图
Jun 28 Python
关于Pytorch的MLP模块实现方式
Jan 07 Python
python列表推导和生成器表达式知识点总结
Jan 10 Python
python实现mask矩阵示例(根据列表所给元素)
Jul 30 Python
Python关于拓扑排序知识点讲解
Jan 04 Python
python urllib库的使用详解
Apr 13 Python
Python编程实现两个文件夹里文件的对比功能示例【包含内容的对比】
Jun 20 #Python
Python中表达式x += y和x = x+y 的区别详解
Jun 20 #Python
回调函数的意义以及python实现实例
Jun 20 #Python
Python处理Excel文件实例代码
Jun 20 #Python
python构建自定义回调函数详解
Jun 20 #Python
Python实现完整的事务操作示例
Jun 20 #Python
python3.4用循环往mysql5.7中写数据并输出的实现方法
Jun 20 #Python
You might like
php设计模式 Prototype (原型模式)代码
2011/06/26 PHP
php eval函数用法 PHP中eval()函数小技巧
2012/10/31 PHP
Smarty局部缓存的几种方法简介
2014/06/17 PHP
php实现通过cookie换肤的方法
2015/07/13 PHP
php实现按天数、星期、月份查询的搜索框
2016/05/02 PHP
php页面跳转session cookie丢失导致不能登录等问题的解决方法
2016/12/12 PHP
tp5(thinkPHP5)框架实现多数据库查询的方法
2019/01/10 PHP
javascript 设计模式之单体模式 面向对象学习基础
2010/04/18 Javascript
jQuery autocomplate 自扩展插件、自动完成示例代码
2011/03/28 Javascript
JavaScript中的toUTCString()方法使用详解
2015/06/12 Javascript
jquery实现点击变换导航样式的方法
2015/08/31 Javascript
谈谈impress.js初步理解
2015/09/09 Javascript
浅析JavaScript访问对象属性和方法及区别
2015/11/16 Javascript
jquery ui dialog替代confirm实例分析
2016/01/25 Javascript
js中document.referrer实现移动端返回上一页
2017/02/22 Javascript
微信小程序 支付功能(前端)的实现
2017/05/24 Javascript
webpack 代码分离优化快速指北
2019/05/18 Javascript
Javascript原型链及instanceof原理详解
2020/05/25 Javascript
[01:02:32]DOTA2-DPC中国联赛 正赛 iG vs PSG.LGD BO3 第二场 2月26日
2021/03/11 DOTA
Python数据分析库pandas基本操作方法
2018/04/08 Python
Python2.7 实现引入自己写的类方法
2018/04/29 Python
详解Python with/as使用说明
2018/12/13 Python
python将处理好的图像保存到指定目录下的方法
2019/01/10 Python
pyqt弹出新对话框,以及关闭对话框获取数据的实例
2019/06/18 Python
使用python对多个txt文件中的数据进行筛选的方法
2019/07/10 Python
Python解析命令行读取参数之argparse模块
2019/07/26 Python
PyTorch中Tensor的维度变换实现
2019/08/18 Python
python异常处理之try finally不报错的原因
2020/05/18 Python
python如何爬取动态网站
2020/09/09 Python
伯利陶器:Burleigh Pottery
2018/01/03 全球购物
美国体育用品商店:Academy Sports + Outdoors
2020/01/04 全球购物
科室工作个人总结的自我评价
2013/10/29 职场文书
2015年项目工作总结
2015/04/29 职场文书
2016初一新生军训心得体会
2016/01/11 职场文书
2016年119消防宣传日活动总结
2016/04/05 职场文书
js基于div丝滑实现贝塞尔曲线
2022/09/23 Javascript