hashlib主要提供字符加密功能,将md5和sha模块整合到了一起,支持md5,sha1, sha224, sha256, sha384, sha512等算法。
在学习hashlib模块之前,先来看看py2.x与py3.x对于这个模块的说明。
py2.x hashlib module new(name, string='') - returns a new hash object implementing the #返回值为一个hash对象 given hash function; initializing the hash using the given string data. Named constructor functions are also available, these are much faster than using new(): md5(), sha1(), sha224(), sha256(), sha384(), and sha512() #python2.x提供的加密算法 More algorithms may be available on your platform but the above are guaranteed to exist. NOTE: If you want the adler32 or crc32 hash functions they are available in the zlib module. #如果想使用adler32和crc32,就导入zlib库 Choose your hash function wisely. Some have known collision weaknesses. sha384 and sha512 will be slow on 32 bit platforms.#sha384和sha512在32位平台效率很低 Hash objects have these methods: - update(arg): Update the hash object with the string arg. - digest(): Return the digest of the strings passed to the update() method so far. This may contain non-ASCII characters, including NUL bytes. - hexdigest(): Like digest() except the digest is returned as a string of double length, containing only hexadecimal digits. - copy(): Return a copy (clone) of the hash object. This can be used to efficiently compute the digests of strings that share a common initial substring.
hashlib module - A common interface to many hash functions. new(name, data=b'', **kwargs) - returns a new hash object implementing the given hash function; initializing the hash using the given binary data. Named constructor functions are also available, these are faster than using new(name): md5(), sha1(), sha224(), sha256(), sha384(), sha512(), blake2b(), blake2s(), sha3_224, sha3_256, sha3_384, sha3_512, shake_128, and shake_256. More algorithms may be available on your platform but the above are guaranteed to exist. See the algorithms_guaranteed and algorithms_available attributes to find out what algorithm names can be passed to new(). NOTE: If you want the adler32 or crc32 hash functions they are available in the zlib module. Choose your hash function wisely. Some have known collision weaknesses. sha384 and sha512 will be slow on 32 bit platforms. Hash objects have these methods: - update(arg): Update the hash object with the bytes in arg. Repeated calls are equivalent to a single call with the concatenation of all the arguments. - digest(): Return the digest of the bytes passed to the update() method so far. - hexdigest(): Like digest() except the digest is returned as a unicode object of double length, containing only hexadecimal digits. - copy(): Return a copy (clone) of the hash object. This can be used to efficiently compute the digests of strings that share a common initial substring.
从上面的表述我们可以看出,在py2.x环境下,如果要加密一个字符串可以按照如下格式:
>>> import hashlib >>> m = hashlib.md5() >>> m.update("Nobody inspects")#主意这里和py3.x不同 >>> m.update(" the spammish repetition") >>> m.digest() '\\xbbd\\x9c\\x83\\xdd\\x1e\\xa5\\xc9\\xd9\\xde\\xc9\\xa1\\x8d\\xf0\\xff\\xe9'
>> hashlib.sha224("Nobody inspects the spammish repetition").hexdigest()
'a4337bc45a8fc544c03f52dc550cd6e1e87021bc896588bd79e901e2'
在py3.x环境下,如果要加密一个字符串可以按照如下格式:
>>> import hashlib >>> m = hashlib.md5() >>> m.update(b"Nobody inspects") >>> m.update(b" the spammish repetition") >>> m.digest() b'\\xbbd\\x9c\\x83\\xdd\\x1e\\xa5\\xc9\\xd9\\xde\\xc9\\xa1\\x8d\\xf0\\xff\\xe9'
>>> hashlib.sha224(b"Nobody inspects the spammish repetition").hexdigest()
'a4337bc45a8fc544c03f52dc550cd6e1e87021bc896588bd79e901e2'
1.模块提供的常数
hash.digest_size The size of the resulting hash in bytes.#返回hash结果的字节数 hash.block_size The internal block size of the hash algorithm in bytes.#返回hash算法内部块的字节数
2.hash对象拥有的方法
hash.update(arg) Update the hash object with the string arg.
#m.update(a);
#m.update(b)
#上面两步等价于m.update(a+b).也就是对于同一字符串用不同值加密,就等价于用这两种加密字符之和再加密 hash.digest() Return the digest of the strings passed to the update() method so far. This is a string of digest_size bytes which may contain non-ASCII characters, including null bytes. hash.hexdigest() Like digest() except the digest is returned as a string of double length, containing only hexadecimal digits. This may be used to exchange the value safely in email or other non-binary environments. hash.copy() Return a copy (“clone”) of the hash object. This can be used to efficiently compute the digests of strings that share a common initial substring.
以上四种方法,在py2.x和py3.x没有差别,只不过在传入参数有点区别。
3.例子
#####py2.7,以下两种方式没区别########## import hashlib string = 'chenwei' md5 = hashlib.md5() # 获得一个md5对象 print md5 md5.update(string) # 用string来更新上面获得的md5对象 res = md5.hexdigest() # 输出加密后的字符 print "md5加密的结果为:",res md5 = hashlib.md5() # 获得一个md5对象 print md5 md5.update('chenwei') # 用string来更新上面获得的md5对象 res = md5.hexdigest() # 输出加密后的字符 print "md5加密的结果为:",res #####以下编译环境py3.6,注意看两种方式区别#### import hashlib string = 'chenwei' md5 = hashlib.md5() # 获得一个md5对象 print(md5) md5.update(string.encode("utf-8")) # 用string来更新上面获得的md5对象 res = md5.hexdigest() # 输出加密后的字符 print("md5加密的结果为:", res) import hashlib md5 = hashlib.md5() # 获得一个md5对象 print(md5) md5.update(b'chenwei') # 用string来更新上面获得的md5对象 res = md5.hexdigest() # 输出加密后的字符 print("md5加密的结果为:", res)
如果需要加密的字符串长度较长,可以分为两次加密,其加密效果与一次加密是一样的。看下面代码:
######py2.x代码,py3.x类型,这里就不写了###### md5 = hashlib.md5() md5.update("how to use md5 in python hashlib?") res = md5.hexdigest() #返回十六进制的hash值 res2 = md5.digest() #返回二进制的hash值 print res,res2 md5 = hashlib.md5() md5.update("how to use md5 in ") md5.update("python hashlib?") res = md5.hexdigest() # 返回十六进制的hash值 res2 = md5.digest() # 返回二进制的hash值 print res,res2 上面种情况是一样的。
其他算法如:sha1(), sha224(), sha256(), sha384(), and sha512()与md5用法一样,就把上面的md5换成sha1....等等即可。
4.应用
任何允许用户登录的网站都会存储用户登录的用户名和口令。如果以明文保存用户口令,如果数据库泄露,所有用户的口令就落入黑客的手里。此外,网站运维人员是可以访问数据库的,也就是能获取到所有用户的口令。正确的保存口令的方式是不存储用户的明文口令,而是存储用户口令的摘要,比如MD5:当用户登录时,首先计算用户输入的明文口令的MD5,然后和数据库存储的MD5对比,如果一致,说明口令输入正确,如果不一致,口令肯定错误。
实例:模拟登陆加密程序
#python3.6 import hashlib def md5(arg): hash = hashlib.md5(bytes('Davve;.',encoding = 'utf-8')) hash.update(bytes(arg,encoding = 'utf-8')) return hash.hexdigest() def register(user,pwd): with open("db",'a',encoding='utf-8') as f: tmp = user + '|' + md5(pwd) f.write(tmp) def login(user,pwd): with open("db",'r',encoding='utf-8') as f: for line in f: u,p = line.strip().split("|") if u == user and p == md5(pwd): #加密是一次性的,不能反解 return True i = input("1:登陆,2:注册\n") ': usr = input("用户名:") pwd = input("密码:") register(usr,pwd) ': usr = input("用户名:") pwd = input("密码:") r = login(usr,pwd) if r: print("登陆成功") else: print("登陆失败")