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根据文件大小打log日志
Oct 09 Python
Python下线程之间的共享和释放示例
May 04 Python
Python的Django框架中从url中捕捉文本的方法
Jul 20 Python
Python对象类型及其运算方法(详解)
Jul 05 Python
Python实现基于TCP UDP协议的IPv4 IPv6模式客户端和服务端功能示例
Mar 22 Python
python3实现163邮箱SMTP发送邮件
May 22 Python
python中join()方法介绍
Oct 11 Python
python样条插值的实现代码
Dec 17 Python
python and or用法详解
Jun 26 Python
python脚本调用iftop 统计业务应用流量的思路详解
Oct 11 Python
Python如何基于Tesseract实现识别文字功能
Jun 05 Python
Python的信号库Blinker用法详解
Dec 31 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
教你如何快捷的使用cmd访问mysql小技巧
2014/05/26 PHP
php将数组转换成csv格式文件输出的方法
2015/03/14 PHP
PHP 返回数组后处理方法(开户成功后弹窗提示)
2017/07/03 PHP
PHP序列化和反序列化深度剖析实例讲解
2020/12/29 PHP
Javascript的一种模块模式
2008/03/22 Javascript
return false;和e.preventDefault();的区别
2010/07/11 Javascript
在jquery中combobox多选的不兼容问题总结
2013/12/24 Javascript
Extjs grid添加一个图片状态或者按钮的方法
2014/04/03 Javascript
jquery 扑捉回车键事件代码
2014/04/24 Javascript
JavaScript生成的动态下雨背景效果实现方法
2015/02/25 Javascript
swtich/if...else的替代语句
2015/08/16 Javascript
JS实现淘宝支付宝网站的控制台菜单效果
2015/09/28 Javascript
详谈JavaScript的闭包及应用
2017/01/17 Javascript
React学习之事件绑定的几种方法对比
2017/09/24 Javascript
解决Vue使用mint-ui loadmore实现上拉加载与下拉刷新出现一个页面使用多个上拉加载后冲突问题
2017/11/07 Javascript
JavaScript实现全选取消效果
2017/12/14 Javascript
JavaScript解析及序列化JSON的方法实例分析
2019/01/04 Javascript
Python中的闭包详细介绍和实例
2014/11/21 Python
Python中最常用的操作列表的几种方法归纳
2015/04/24 Python
python2.7实现邮件发送功能
2018/12/12 Python
Python 的AES加密与解密实现
2019/07/09 Python
python opencv捕获摄像头并显示内容的实现
2019/07/11 Python
python利用itertools生成密码字典并多线程撞库破解rar密码
2019/08/12 Python
python GUI库图形界面开发之PyQt5打开保存对话框QFileDialog详细使用方法与实例
2020/02/27 Python
Pycharm内置终端及远程SSH工具的使用教程图文详解
2020/03/19 Python
CSS3中引入多种自定义字体font-face
2020/06/12 HTML / CSS
input元素的url类型和email类型简介
2012/07/11 HTML / CSS
莫斯科的韩国化妆品店:Sifo
2019/12/04 全球购物
葛优非诚勿扰搞笑征婚台词
2014/03/17 职场文书
会计人员岗位职责
2014/03/19 职场文书
运动会拉拉队口号
2014/06/09 职场文书
教师查摆问题及整改措施
2014/10/11 职场文书
单方离婚协议书范本2014
2014/10/28 职场文书
幼儿园音乐教学反思
2016/02/18 职场文书
golang生成vcf通讯录格式文件详情
2022/03/25 Golang
win sever 2022如何占用操作主机角色
2022/06/25 Servers