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 urllib模块urlopen()与urlretrieve()详解
Nov 01 Python
深度定制Python的Flask框架开发环境的一些技巧总结
Jul 12 Python
python 打印直角三角形,等边三角形,菱形,正方形的代码
Nov 21 Python
详解Python自建logging模块
Jan 29 Python
使用python来调用CAN通讯的DLL实现方法
Jul 03 Python
python 的 scapy库,实现网卡收发包的例子
Jul 23 Python
django 通过URL访问上传的文件方法
Jul 28 Python
Python+OpenCV实现实时眼动追踪的示例代码
Nov 11 Python
JupyterNotebook 输出窗口的显示效果调整方法
Apr 13 Python
浅谈django框架集成swagger以及自定义参数问题
Jul 07 Python
详解python日志输出使用配置文件格式
Feb 10 Python
Python趣味挑战之实现简易版音乐播放器
May 28 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.ini实现Mysql导入数据库文件最大限制的修改方法
2007/12/11 PHP
Linux安装配置php环境的方法
2016/01/14 PHP
Yii2中设置与获取别名的函数(setAlias和getAlias)用法分析
2016/07/25 PHP
imagettftext() 失效,不起作用
2021/03/09 PHP
JavaScript 计算图片加载数量的代码
2011/01/01 Javascript
Jquery操作radio的简单实例
2014/01/06 Javascript
JavaScript实现简单图片滚动附源码下载
2014/06/17 Javascript
jQuery实现仿腾讯迷你首页选项卡效果代码
2015/09/17 Javascript
基于insertBefore制作简单的循环插空效果
2015/09/21 Javascript
JavaScript实现点击按钮切换网页背景色的方法
2015/10/17 Javascript
基于React.js实现原生js拖拽效果引发的思考
2016/03/30 Javascript
JS中的==运算: [''] == false —&gt;true
2016/07/24 Javascript
JS键盘版计算器的制作方法
2016/12/03 Javascript
vue 实现边输入边搜索功能的实例讲解
2018/09/16 Javascript
vue打包之后生成一个配置文件修改接口的方法
2018/12/09 Javascript
深入理解 JS 垃圾回收
2019/06/03 Javascript
layui table复选框禁止某几条勾选的实例
2019/09/20 Javascript
javascript+css实现俄罗斯方块小游戏
2020/06/28 Javascript
Vue-cli4 配置 element-ui 按需引入操作
2020/09/11 Javascript
[42:32]DOTA2上海特级锦标赛B组资格赛#2 Fnatic VS Spirit第二局
2016/02/27 DOTA
用smtplib和email封装python发送邮件模块类分享
2014/02/17 Python
python实现中文分词FMM算法实例
2015/07/10 Python
python爬虫入门教程--优雅的HTTP库requests(二)
2017/05/25 Python
Python利用字典将两个通讯录文本合并为一个文本实例
2018/01/16 Python
django数据模型on_delete, db_constraint的使用详解
2019/12/24 Python
python 函数中的参数类型
2020/02/11 Python
C语言怎样定义和声明全局变量和函数最好
2013/11/26 面试题
入团者的自我评价分享
2013/12/02 职场文书
差生评语大全
2014/05/04 职场文书
企业员工薪酬方案
2014/06/04 职场文书
工厂门卫的岗位职责
2014/07/27 职场文书
小学五一劳动节活动总结
2015/02/09 职场文书
公诉意见书范文
2015/06/05 职场文书
2015年库房管理工作总结
2015/10/14 职场文书
大学生党员暑假实践(活动总结)
2019/08/21 职场文书
深入理解 Golang 的字符串
2022/05/04 Golang