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 相关文章推荐
Python3解决棋盘覆盖问题的方法示例
Dec 07 Python
python3 破解 geetest(极验)的滑块验证码功能
Feb 24 Python
python批量实现Word文件转换为PDF文件
Mar 15 Python
浅谈配置OpenCV3 + Python3的简易方法(macOS)
Apr 02 Python
python中in在list和dict中查找效率的对比分析
May 04 Python
查看django执行的sql语句及消耗时间的两种方法
May 29 Python
Python 实现遥感影像波段组合的示例代码
Aug 04 Python
基于TensorFlow常量、序列以及随机值生成实例
Jan 04 Python
Python发起请求提示UnicodeEncodeError错误代码解决方法
Apr 21 Python
在Mac中配置Python虚拟环境过程解析
Jun 22 Python
python各种excel写入方式的速度对比
Nov 10 Python
浅析python实现动态规划背包问题
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
PHP 文件写入和读取操作实例详解【必看篇】
2019/11/04 PHP
关于hashchangebroker和statehashable的补充文档
2011/08/08 Javascript
JavaScript自定义方法实现trim()、Ltrim()、Rtrim()的功能
2013/11/03 Javascript
自己用jQuery写了一个图片的马赛克消失效果
2014/05/04 Javascript
JQuery弹出层示例可自定义
2014/05/19 Javascript
Javascript中的高阶函数介绍
2015/03/15 Javascript
javascript数据结构与算法之检索算法
2015/04/04 Javascript
javascript实现textarea中tab键的缩排处理方法
2015/06/26 Javascript
浅谈javascript的call()、apply()、bind()的用法
2016/02/21 Javascript
AngularJs自定义服务之实现签名和加密
2016/08/02 Javascript
js监听键盘事件的方法_原生和jquery的区别详解
2016/10/10 Javascript
js return返回多个值,通过对象的属性访问方法
2017/02/21 Javascript
JS实现新建文件夹功能
2017/06/17 Javascript
JavaScript中正则表达式判断匹配规则及常用方法
2017/08/03 Javascript
layer.js open 隐藏滚动条的例子
2019/09/05 Javascript
Python使用matplotlib绘图无法显示中文问题的解决方法
2018/03/14 Python
对Python中plt的画图函数详解
2018/11/07 Python
python opencv 图像拼接的实现方法
2019/06/27 Python
Numpy中对向量、矩阵的使用详解
2019/10/29 Python
TensorFlow tf.nn.conv2d实现卷积的方式
2020/01/03 Python
Python3批量创建Crowd用户并分配组
2020/05/20 Python
Django实现微信小程序支付的示例代码
2020/09/03 Python
python中zip()函数遍历多个列表方法
2021/02/18 Python
详解Html5原生拖拽操作
2018/01/12 HTML / CSS
使用phonegap进行本地存储的实现方法
2017/03/31 HTML / CSS
Forever 21美国官网:美国标志性快时尚品牌
2017/02/20 全球购物
L’AGENCE官网:加州女装品牌
2018/06/03 全球购物
意大利香水和化妆品购物网站:Parfimo.it
2019/10/06 全球购物
俄罗斯茶和咖啡网上商店:Tea.ru
2021/01/26 全球购物
艺术系大学生毕业个人自我评价
2013/09/19 职场文书
一帮一活动总结
2014/05/08 职场文书
反腐倡廉演讲稿
2014/05/22 职场文书
关键在于落实心得体会
2014/09/03 职场文书
单位未婚证明范本
2014/11/25 职场文书
环卫工作个人总结
2015/03/04 职场文书
施工安全责任协议书
2016/03/23 职场文书