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和bash统计CPU利用率的方法
Jul 10 Python
Python面向对象特殊成员
Apr 24 Python
Python Requests库基本用法示例
Aug 20 Python
Python中单线程、多线程和多进程的效率对比实验实例
May 14 Python
pip指定python位置安装软件包的方法
Jul 12 Python
tensorflow使用range_input_producer多线程读取数据实例
Jan 20 Python
详解Python3中的 input() 函数
Mar 18 Python
Python实现计算图像RGB均值方式
Jun 04 Python
简述python Scrapy框架
Aug 17 Python
Python tkinter界面实现历史天气查询的示例代码
Aug 23 Python
深度学习小工程练习之垃圾分类详解
Apr 14 Python
Python使用scapy模块发包收包
May 07 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加密解密的代码
2006/10/09 PHP
php 数组排序 array_multisort与uasort的区别
2011/03/24 PHP
PHP中开启gzip压缩的2种方法
2015/01/31 PHP
Laravel 5框架学习之表单验证
2015/04/08 PHP
如何解决PHP无法实现多线程的问题
2015/09/25 PHP
Thinkphp 框架扩展之类库扩展操作详解
2020/04/23 PHP
使用Rancher在K8S上部署高性能PHP应用程序的教程
2020/07/10 PHP
JS实现黑色大气的二级导航菜单效果
2015/09/18 Javascript
javascript制作照片墙及制作过程中出现的问题
2016/04/04 Javascript
jQuery实现最简单的切换图效果【可兼容IE6、火狐、谷歌、opera等】
2016/09/04 Javascript
View.post() 不靠谱的地方你知道多少
2017/08/29 Javascript
vue-auto-focus: 控制自动聚焦行为的 vue 指令方法
2018/08/25 Javascript
详解Element 指令clickoutside源码分析
2019/02/15 Javascript
VUE子组件向父组件传值详解(含传多值及添加额外参数场景)
2020/09/01 Javascript
vue 在服务器端直接修改请求的接口地址
2020/12/19 Vue.js
vue实现一个获取按键展示快捷键效果的Input组件
2021/01/13 Vue.js
Python创建xml的方法
2015/03/10 Python
Python脚本暴力破解栅栏密码
2015/10/19 Python
python3.6+opencv3.4实现鼠标交互查看图片像素
2018/02/26 Python
Python3中exp()函数用法分析
2019/02/19 Python
Python字符串格式化输出代码实例
2019/11/22 Python
使用已经得到的keras模型识别自己手写的数字方式
2020/06/29 Python
好莱坞百老汇御用王牌美妆:Koh Gen Do 江原道
2018/04/03 全球购物
Tom Dixon官网:英国照明及家具设计和制造公司
2019/03/01 全球购物
"火柴棍式"程序员面试题
2014/03/16 面试题
实习报告评语
2014/04/26 职场文书
幼儿园优秀班主任事迹材料
2014/05/14 职场文书
田径运动会通讯稿
2014/09/13 职场文书
2015年工程师工作总结
2015/04/30 职场文书
心理健康教育主题班会
2015/08/13 职场文书
决心书格式范文
2015/09/23 职场文书
严以律己专题学习研讨会发言材料
2015/11/09 职场文书
新手入门Mysql--sql执行过程
2021/06/20 MySQL
redis数据结构之压缩列表
2022/03/21 Redis
《游戏王:大师决斗》将推出新卡牌包4月4日上线
2022/03/31 其他游戏
 分享一个Python 遇到数据库超好用的模块
2022/04/06 Python