如何hash一段文本
了解编程的人一定听说过hash,hash是一种思想,是一种让人着迷的思想。给定算法和文本,hash算法会将一些文本转换成另一些文本,如果文本和算法是不变的,hash出来的结果也会是一样的,并且经过hash之后的文本很难推出来原文本,这就是hash的核心思想。有些小伙伴就会想hash有什么用呢?hash很有用,这个hash过程就说明了它很有用,经过hash过的文本很难推出来原文本,那么这个hash之后的文本可以用来验证原文本的正确性,所以hash可以用在消息验证上,另外,hash也用在其他方面。
既然hash这么有用,那么就来学习一下python里是如何hash一个文本的,大家首先要明白hash的算法很多,每个算法的实现方式是不一样的,然后,python里有两个模块可以hash文本,这两个模块是hashlib和hmac。使用模块hash文本的过程很简单,按照PEP247的介绍[1],一个hash模块应该提供这些接口:
- new:创建一个新的哈希对象并返回它;
- digest_size:创建的哈希对象产生的摘要的大小,以字节为单位;
- copy:返回此哈希对象的单独副本;
- digest:以包含8位数据的字符串形式返回此哈希对象的哈希值;
- hexdigest:以包含十六进制数字的字符串形式返回此哈希对象的哈希值;
- update:将哈希字符串转换为哈希对象的当前状态,简单理解就是追加hash字符串。
看一下代码,hash的文本要求是二进制的:
""" 如何hash一个文本
1.使用hashlib模块的各种hash函数来hash文本
2.使用hmac模块来hash带键的文本(双保险)
the statistics of this file:
lines(count) understand_level(h/m/l) classes(count) functions(count) fields(count)
000000000088 ----------------------l 00000000000000 0000000000000000 ~~~~~~~~~~~~~
"""
import time
import hashlib
import hmac
__author__ = '与C同行'
if __name__ == '__main__':
print(f'当前时间:{time.ctime()}')
print('使用hashlib来hash文本')
print('使用new函数创建md5算法来hash文本')
print('hello使用md5之后的hash值:')
hello_hash = hashlib.new('md5', b'hello')
hello_hash_8bit_value = hello_hash.digest()
print('8位数据的字符串形式')
print(hello_hash_8bit_value)
hello_hash_16_value = hello_hash.hexdigest()
print('16进制的数字形式')
print(hello_hash_16_value)
print(f'md5的结果长度:{hello_hash.digest_size}')
print()
print('hello world使用md5之后的hash值:')
hello_hash.update(b' world')
hello_world_8bit_value = hello_hash.digest()
print('8位数据的字符串形式')
print(hello_world_8bit_value)
hello_world_hash_16_value = hello_hash.hexdigest()
print('16进制的数字形式')
print(hello_world_hash_16_value)
print()
print('使用md5函数创建md5算法来hash文本')
print('hello使用md5之后的hash值:')
hello_hash = hashlib.md5('hello'.encode('utf8'))
hello_hash_8bit_value = hello_hash.digest()
print('8位数据的字符串形式')
print(hello_hash_8bit_value)
hello_hash_16_value = hello_hash.hexdigest()
print('16进制的数字形式')
print(hello_hash_16_value)
print()
print('即使是长文本也会hash成相应长度的值')
long_text_hash = hashlib.md5('今天去了花园呆了很久,然后去吃了点东西,'
'最后到随便逛了逛就回家了,'.encode('utf8'))
long_text_hash_8bit_value = long_text_hash.digest()
print('长文本hash结果:')
print('8位数据的字符串形式')
print(long_text_hash_8bit_value)
long_text_hash_16_value = long_text_hash.hexdigest()
print('16进制的数字形式')
print(long_text_hash_16_value)
print()
print('使用hmac模块来hash文本')
print('使用new函数来hash')
print('hello文本加键public之后的hash值:')
hello_key_hash = hmac.new(b'public', b'hello', 'md5')
hello_key_hash_8bit_value = hello_key_hash.digest()
print('8位数据的字符串形式')
print(hello_key_hash_8bit_value)
hello_key_hash_16_value = hello_key_hash.hexdigest()
print('16进制的数字形式')
print(hello_key_hash_16_value)
print(f'md5的结果长度:{hello_key_hash.digest_size}')
print()
print('使用HMAC类来操作hash')
print('hello文本加键private之后的hash值:')
hmac_sha1 = hmac.HMAC(b'private', b'hello', 'sha1')
hmac_sha1_hash_8bit_value = hmac_sha1.digest()
print('8位数据的字符串形式')
print(hmac_sha1_hash_8bit_value)
hmac_sha1_hash_16_value = hmac_sha1.hexdigest()
print('16进制的数字形式')
print(hmac_sha1_hash_16_value)
print(f'sha1的结果长度:{hmac_sha1.digest_size}')
print()
看一下结果:
可以看到不同的算法导致相同的文本被hash成不同的结果,同样的文本使用同样的算法会hash成同样的文本,另外,hmac模块的hash算法使用了参数key进行加密,比普通的hash算法要更安全。
参考文章
[1] https://www.python.org/dev/peps/pep-0247/
喜欢学习python的朋友可以关注我的微信公众号“与C同行”: