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的GUI框架PySide的安装配置教程
Feb 16 Python
Python遍历目录并批量更换文件名和目录名的方法
Sep 19 Python
python实现的多线程端口扫描功能示例
Jan 21 Python
利用Python查看目录中的文件示例详解
Aug 28 Python
TensorFlow入门使用 tf.train.Saver()保存模型
Apr 24 Python
Python推导式简单示例【列表推导式、字典推导式与集合推导式】
Dec 04 Python
对python 中re.sub,replace(),strip()的区别详解
Jul 22 Python
Python 用matplotlib画以时间日期为x轴的图像
Aug 06 Python
python实现tail实时查看服务器日志示例
Dec 24 Python
Python安装OpenCV的示例代码
Mar 05 Python
Python判断三段线能否构成三角形的代码
Apr 12 Python
Django实现简单的分页功能
Feb 22 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加Nginx实现动态裁剪图片方案
2014/03/10 PHP
laravel 框架实现无限级分类的方法示例
2019/10/31 PHP
JavaScript中的其他对象
2008/01/16 Javascript
二级域名或跨域共享Cookies的实现方法
2008/08/07 Javascript
类似GMAIL的Ajax信息反馈显示
2010/02/16 Javascript
JavaScript定义类或函数的几种方式小结
2011/01/09 Javascript
利用jQuery实现可输入搜索文字的下拉框
2013/10/23 Javascript
js与运算符和或运算符的妙用
2014/02/14 Javascript
JavaScript获得表单target属性的方法
2015/04/02 Javascript
AngularJS中实现用户访问的身份认证和表单验证功能
2016/04/21 Javascript
EasyUI中在表单提交之前进行验证
2016/07/19 Javascript
详解RequireJS按需加载样式文件
2017/04/12 Javascript
vue-cli脚手架搭建的项目去除eslint验证的方法
2018/09/29 Javascript
JavaScript实现简单音乐播放器
2020/04/17 Javascript
JSON字符串操作移除空串更改key/value的介绍
2019/01/05 Javascript
JavaScript静态作用域和动态作用域实例详解
2019/06/17 Javascript
详解Element-UI中上传的文件前端处理
2019/08/07 Javascript
Python2中的raw_input() 与 input()
2015/06/12 Python
Python 正则表达式入门(初级篇)
2016/12/07 Python
Python 基础教程之包和类的用法
2017/02/23 Python
fastcgi文件读取漏洞之python扫描脚本
2017/04/23 Python
wxPython多个窗口的基本结构
2019/11/19 Python
python 利用turtle模块画出没有角的方格
2019/11/23 Python
Python包和模块的分发详细介绍
2020/06/19 Python
python import 上级目录的导入
2020/11/03 Python
python+playwright微软自动化工具的使用
2021/02/02 Python
Python使用paramiko连接远程服务器执行Shell命令的实现
2021/03/04 Python
Tripadvisor新西兰:阅读评论,比较价格和酒店预订
2018/02/10 全球购物
丝绸和人造花卉、植物和树木:Nearly Natural
2018/11/28 全球购物
法律系毕业生自荐信范文
2014/03/27 职场文书
消防标语大全
2014/06/07 职场文书
云南省召开党的群众路线教育实践活动总结会议新闻稿
2014/10/21 职场文书
2015年国庆放假通知范文
2015/08/18 职场文书
电力安全教育培训心得体会
2016/01/11 职场文书
使用golang编写一个并发工作队列
2021/05/08 Golang
Python OpenCV超详细讲解读取图像视频和网络摄像头
2022/04/02 Python