摘要算法简介

  Python的hashlib提供了常见的摘要算法,如MD5,SHA1等等。

  什么是摘要算法呢?摘要算法又称哈希算法、散列算法。它通过一个函数,把任意长度的数据转换为一个长度固定的数据串(通常用16进制的字符串表示)。

  举个例子,你写了一篇文章,内容是一个字符串'how to use python hashlib - by Michael',并附上这篇文章的摘要是'2d73d4f15c0db7f5ecb321b6a65e5d6d'。如果有人篡改了  你的文章,并发表为'how to use python hashlib - by Bob',你可以一下子指出Bob篡改了你的文章,因为根据'how to use python hashlib - by Bob'计算出的摘要不同于原始  文章的摘要。

  可见,摘要算法就是通过摘要函数f()对任意长度的数据data计算出固定长度的摘要digest,目的是为了发现原始数据是否被人篡改过。

  摘要算法之所以能指出数据是否被篡改过,就是因为摘要函数是一个单向函数,计算f(data)很容易,但通过digest反推data却非常困难。而且,对原始数据做一个bit的修改,都会导致计  算出的摘要完全不同。

  我们以常见的摘要算法MD5为例,计算出一个字符串的MD5值:

>>> import hashlib
>>> md5=hashlib.md5()
>>> md5.update('how to use md5 in python hashlib?'.encode('utf-8'))
>>> print(md5.hexdigest())

  结果如下

d26a53750bc40b38b65a520292f69306

  如果数据线很大,可以分块多次调用update(),最后计算的结果是一样的

>>> import hashlib
>>> md5=hashlib.md5()
>>> md5.update('how to use md5 in '.encode('utf-8'))
>>> md5.update('python hashlib?'.encode('utf-8'))
>>> print(md5.hexdigest())
d26a53750bc40b38b65a520292f69306

  试试改动一个字母,看看计算结果是否一样

  MD5是最常见的摘要算法,速度很快,生成结果是固定的128 bit字节,通常用一个32位的16进制字符串表示。

  另一种常见的摘要算法是SHA1,调用SHA1和调用MD5完全类似:

>>> import hashlib
>>> sha1=hashlib.sha1()
>>> sha1.update('how to use md5 in python hashlib?'.encode('utf-8'))
>>> print(sha1.hexdigest())
b752d34ce353e2916e943dc92501021c8f6bca8c

  SHA1的结果是160 bit字节,通常用一个40位的16进制字符串表示。

  比SHA1更安全的算法是SHA256和SHA512,不过越安全的算法不仅越慢,而且摘要长度更长。

  有没有可能两个不同的数据通过某个摘要算法得到了相同的摘要?完全有可能,因为任何摘要算法都是把无限多的数据集合映射到一个有限的集合中。这种情况称为碰撞,比如Bob试图根  据你的摘要反推出一篇文章'how to learn hashlib in python - by Bob',并且这篇文章的摘要恰好和你的文章完全一致,这种情况也并非不可能出现,但是非常非常困难。

  摘要算法应用

  摘要算法能应用到什么地方?举个常用例子:

  任何允许用户登录的网站都会存储用户登录的用户名和口令。如何存储用户名和口令呢?方法是存到数据库表中:

name password
zhangsan    123456
lisi abc
wangwu abc999

  

  如果以明文保存用户口令,如果数据库泄露,所有用户的口令就落入黑客的手里。此外,网站运维人员是可以访问数据库的,也就是能获取到所有用户的口令。

正确的保存口令的方式是不存储用户的明文口令,而是存储用户口令的摘要,比如MD5:

name  password
zhangsan e10adc3949ba59abbe56e057f20f883e
lisi 900150983cd24fb0d6963f7d28e17f72
wangwu 878ef96e86145580c38c87f0410ad153

  

  当用户登录时,首先计算用户输入的明文口令的MD5,然后和数据库存储的MD5对比,如果一致,说明口令输入正确,如果不一致,口令肯定错误。

  练习

  根据用户输入的登录名和口令模拟实现用户登录的验证

  use_hashlib1.py

# -*- coding: utf-8 -*-
import hashlib, random
#定义生成MD5值函数,接收一个字符串输入返回MD5值
def get_md5(s):
return hashlib.md5(s.encode('utf-8')).hexdigest()
#定义用户类,加盐用户密码为用户输入的密码加随机生成的20位字符然后再生成MD5
class User(object):
def __init__(self, username, password):
self.username = username
self.salt = ''.join([chr(random.randint(48, 122)) for i in range(20)])
self.password = get_md5(password + self.salt)
#模拟生成用户,db为字典key为用户名value为User类实例化后的对象
db = {
'michael': User('michael', '123456'),
'bob': User('bob', 'abc999'),
'alice': User('alice', 'alice2008')
} #模拟登陆输入用户名以及密码
#如果输入的用户名加密码对应则返回True
#例如参数为('michael','123456')则使用db类存储的密码与重新调用函数get_md5()生成的密码进行对比
#调用函数get_md5()传递的参数为用户输入的密码+存储在db里面随机生成的加盐字符串salt
def login(username, password):
user = db[username]
return user.password == get_md5(password+user.salt) print(login('michael','123456'))
print(login('bob','abc999'))

Python3之内建模块hashlib的更多相关文章

  1. Python3 内建模块 hashlib、itertools、HTMLParser、urllib

    Python的hashlib提供了常见的摘要算法,如MD5,SHA1等等. 什么是摘要算法呢?摘要算法又称哈希算法.散列算法.它通过一个函数,把任意长度的数据转换为一个长度固定的数据串(通常用16进制 ...

  2. Python3之内建模块itertools

    python的内建模块itertools提供了非常有用的用于操作迭代对象的函数 首先,我们看看itertools提供的几个无限迭代器 >>> import itertools > ...

  3. Python3之内建模块collections

    collections是python内建的一个集合模块,提供了许多有用的集合类. namedtuple 我们知道tuple可以表示不可变集合,例如,一个点的二维坐标可以表示成 >>> ...

  4. Python3之内建模块datetime

    datetime datetime是python处理日期和时间的标准库 获取当前日期和时间 >>> from datetime import datetime #获取当前的datet ...

  5. Python3之内建模块base64

    Base64是一种用64个字符来表示任意二进制数据的方法. 用记事本打开exe.jpg.pdf这些文件时,我们都会看到一大堆乱码,因为二进制文件包含很多无法显示和打印的字符,所以,如果要让记事本这样的 ...

  6. Python3 内建模块 datetime/collections/base64/struct

    datetime 我们先看如何获取当前日期和时间: >>> from datetime import datetime >>> now = datetime.now ...

  7. 四十五 常用内建模块 hashlib

    Python的hashlib提供了常见的摘要算法,如MD5,SHA1等等. 什么是摘要算法呢?摘要算法又称哈希算法.散列算法.它通过一个函数,把任意长度的数据转换为一个长度固定的数据串(通常用16进制 ...

  8. python基础之内建模块base64

    一.Base64概念 什么是Base64? 按照RFC2045的定义,Base64被定义为:Base64内容传送编码被设计用来把任意序列的8位字节描述为一种不易被人直接识别的形式.(The Base6 ...

  9. python常用内建模块 collections,bs64,struct,hashlib,itertools,contextlib,xml

    #  2  collections 是Python内建的一个集合模块,提供了许多有用的集合类. # 2.1 namedtuple #tuple可以表示不变集合,例如,一个点的二维坐标就可以表示成: p ...

随机推荐

  1. neo4j安装部署

    链接: https://blog.csdn.net/u013946356/article/details/81736232

  2. PHP 将某一字符串转化为变量

    1. $test = 'test'; $var = 'test'; echo  $$var 运行结果为test 2. $this->test = 'test'; $var = 'test'; e ...

  3. 洛谷P1650赛马与codevs 2181 田忌赛马

    洛谷P1650 赛马 题目描述 我国历史上有个著名的故事: 那是在2300年以前.齐国的大将军田忌喜欢赛马.他经常和齐王赛马.他和齐王都有三匹马:常规马,上级马,超级马.一共赛三局,每局的胜者可以从负 ...

  4. python 之 字符串的常用方法

    split()函数: 返回以指定的字符将字符串分割成多个元素的列表 my_str = 'name is wangxiaoming' print(my_str.split()) #默认不写参数表示按空格 ...

  5. 洛谷P1714切蛋糕

    题目 该题目就是求这n个数的前缀和所组成的数组的所有子区间的左端点和右端点相差不超过m,且他们的前缀和差最大,求出这个最大值即可. 而朴素算法肯定会T,而我们发现如果前缀和最大的话,则前缀和的值一定是 ...

  6. shell脚本编程之条件判断

    条件测试类型: 整数测试 字符测试 文件测试 条件测试的表达式的三种方法: 1.[ expression ] 命令测试 2.[[ expression ]] 关键字测试 3.test expressi ...

  7. 《挑战30天C++入门极限》新手入门:C++中堆内存(heap)的概念和操作方法

        新手入门:C++中堆内存(heap)的概念和操作方法 堆内存是什么呢? 我们知道在c/c++中定义的数组大小必需要事先定义好,他们通常是分配在静态内存空间或者是在栈内存空间内的,但是在实际工作 ...

  8. Redis哨兵日常实践

    一.日常操作 指定一个从做新主 有时候需要将当前主节点机器下线,并指定一个高一些性能的从节点接替 将其它从节点的slave-priority配置为0,然后在随意一台 Setinel 执行sentine ...

  9. win10 eclipse连接虚拟机ubuntu中的hdfs

    1.eclipse安装连接hadoop的插件hadoop-eclipse-plugin-2.6.0(注意自己hadoop的版本) 将该插件放在eclipse安装路径的plugins文件夹中. ps:我 ...

  10. ssh端口映射总结

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/boliang319/article/det ...