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程序添加图形化界面的教程
Apr 29 Python
Python去除字符串两端空格的方法
May 21 Python
python学习之第三方包安装方法(两种方法)
Jul 30 Python
Python多线程、异步+多进程爬虫实现代码
Feb 17 Python
python实现神经网络感知器算法
Dec 20 Python
python检测空间储存剩余大小和指定文件夹内存占用的实例
Jun 11 Python
对TensorFlow的assign赋值用法详解
Jul 30 Python
python3正则提取字符串里的中文实例
Jan 31 Python
python中selenium操作下拉滚动条的几种方法汇总
Jul 14 Python
Ubuntu18.04安装 PyCharm并使用 Anaconda 管理的Python环境
Apr 08 Python
python实现定时发送邮件到指定邮箱
Dec 23 Python
Python3的进程和线程你了解吗
Mar 16 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 表单验证实现代码
2009/03/10 PHP
php牛逼的面试题分享
2013/01/18 PHP
php计算数组不为空元素个数的方法
2014/01/27 PHP
使用PHP和HTML5 FormData实现无刷新文件上传教程
2014/09/06 PHP
PHP 配置后台登录以及模板引入
2017/01/24 PHP
PHP+jQuery实现双击修改table表格功能示例
2019/02/21 PHP
对laravel的csrf 防御机制详解,及form中csrf_token()的存在介绍
2019/10/24 PHP
使用Rancher在K8S上部署高性能PHP应用程序的教程
2020/07/10 PHP
jQuery 获取对象 根据属性、内容匹配, 还有表单元素匹配
2010/05/31 Javascript
如何使用jQuery Draggable和Droppable实现拖拽功能
2013/07/05 Javascript
Ajax请求在数据量大的时候出现超时的解决方法
2014/02/27 Javascript
单击和双击事件的冲突处理示例代码
2014/04/03 Javascript
js分页代码分享
2014/04/28 Javascript
node.js中的fs.readFileSync方法使用说明
2014/12/15 Javascript
jquery实现鼠标点击后展开列表内容的导航栏效果
2015/09/14 Javascript
三分钟带你玩转jQuery.noConflict()
2016/02/15 Javascript
JS函数的定义与调用方法推荐
2016/05/12 Javascript
bootstrap 设置checkbox部分选中效果
2017/04/20 Javascript
关于预加载InstantClick的问题解决方法
2017/09/12 Javascript
vue  自定义组件实现通讯录功能
2018/09/30 Javascript
JavaScript实现邮箱后缀提示功能的示例代码
2018/12/13 Javascript
vue中引入第三方字体文件的方法示例
2018/12/17 Javascript
操作按钮悬浮固定在微信小程序底部的实现代码
2019/08/02 Javascript
node获取客户端ip功能简单示例
2019/08/24 Javascript
python求pi的方法
2014/10/08 Python
python中的内置函数max()和min()及mas()函数的高级用法
2018/03/29 Python
Python使用Matplotlib模块时坐标轴标题中文及各种特殊符号显示方法
2018/05/04 Python
Python pandas库中的isnull()详解
2019/12/26 Python
PyQt5实现登录页面
2020/05/30 Python
phpquery中文手册
2021/03/18 PHP
美国综合购物商城:UnbeatableSale.com
2018/11/28 全球购物
Wolford法国官网:奥地利奢侈内衣品牌
2020/08/11 全球购物
新闻系毕业生推荐信
2013/11/16 职场文书
技校个人求职信范文
2014/01/25 职场文书
2016春节放假通知范文
2015/08/18 职场文书
Mysql 数据库中的 redo log 和 binlog 写入策略
2022/04/26 MySQL