10.2. hashlib — 加密哈希算法

未匹配的标注

目标: 加密哈希与信息摘要

 hashlib 哈希库模块提供了许多哈希算法的 API 支持。哈希算法在中文又被称为散列函数/算法,此译文中将统称哈希。想使用具体某一个哈希算法,只需要使用对应的构造函数 new() 来创建对应的哈希对象。不论想使用哪一种具体的哈希算法,在创建哈希对象后的操作均为一致。

哈希算法

 hashlib 使用开源软件库 OpenSSL 作为底层驱动, 因此, hashlib 支持所有 OpenSSL 提供的算法,比如

  • md5
  • sha1
  • sha224
  • sha256
  • sha384
  • sha512

具体某一种哈希算法的支持与否取决于操作系统,因为有些哈希算法依赖特定的底层驱动库。查看全平台支持的哈希算法可以使用 algorithms_guaranteed ;查看当前使用平台所支持的哈希算法可使用 algorithms_available

hashlib_algorithms.py

import hashlib

print('Guaranteed:\n{}\n'.format(
    ', '.join(sorted(hashlib.algorithms_guaranteed))))
print('Available:\n{}'.format(
    ', '.join(sorted(hashlib.algorithms_available))))
$ python3 hashlib_algorithms.py

Guaranteed:
blake2b, blake2s, md5, sha1, sha224, sha256, sha384, sha3_224,
sha3_256, sha3_384, sha3_512, sha512, shake_128, shake_256

Available:
DSA, DSA-SHA, MD4, MD5, RIPEMD160, SHA, SHA1, SHA224, SHA256,
SHA384, SHA512, blake2b, blake2s, dsaEncryption, dsaWithSHA,
ecdsa-with-SHA1, md4, md5, ripemd160, sha, sha1, sha224, sha256,
sha384, sha3_224, sha3_256, sha3_384, sha3_512, sha512,
shake_128, shake_256, whirlpool

简单数据

这个部分的所有例子都将使用如下简单数据:

hashlib_data.py

import hashlib

lorem = '''Lorem ipsum dolor sit amet, consectetur adipisicing
elit, sed do eiusmod tempor incididunt ut labore et dolore magna
aliqua. Ut enim ad minim veniam, quis nostrud exercitation
ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis
aute irure dolor in reprehenderit in voluptate velit esse cillum
dolore eu fugiat nulla pariatur. Excepteur sint occaecat
cupidatat non proident, sunt in culpa qui officia deserunt
mollit anim id est laborum.'''

MD5 例子

要为一个数据块(这里是一个 unicode 字符串转化成对应的字节串)计算 MD5 哈希值或者 摘要, 首先要创建哈希对象, 然后为这个对象添加数据并且进行 digest() 或者 hexdigest() 调用。

hashlib_md5.py

import hashlib

from hashlib_data import lorem

h = hashlib.md5()
h.update(lorem.encode('utf-8'))
print(h.hexdigest())

这个例子使用 hexdigest() 方法而不是使用 digest()。 是因为它的输出是格式化的,可以被清晰的打印出来。如果二进制的摘要值可以接受的话,可以使用 digest()

$ python3 hashlib_md5.py

3f2fd2c9e25d60fb0fa5d593b802b7a8

SHA1 例子

一个 SHA1 摘要是以相似的方式计算出来的。

hashlib_sha1.py

import hashlib

from hashlib_data import lorem

h = hashlib.sha1()
h.update(lorem.encode('utf-8'))
print(h.hexdigest())

在这个例子中,摘要值与上面的例子不一样,因为算法从 MD5 换成了 SHA1。

$ python3 hashlib_sha1.py

ea360b288b3dd178fe2625f55b2959bf1dba6eef

使用名字创建哈希

有时通过字符串对算法进行引用比直接使用构造函数更加方便。例如,这样可以将哈希类型直接写入配置文件中,这是很方便的。在这种情况下,使用 new() 去创建一个哈希计算器。

hashlib_new.py

import argparse
import hashlib
import sys

from hashlib_data import lorem

parser = argparse.ArgumentParser('hashlib demo')
parser.add_argument(
    'hash_name',
    choices=hashlib.algorithms_available,
    help='the name of the hash algorithm to use',
)
parser.add_argument(
    'data',
    nargs='?',
    default=lorem,
    help='the input data to hash, defaults to lorem ipsum',
)
args = parser.parse_args()

h = hashlib.new(args.hash_name)
h.update(args.data.encode('utf-8'))
print(h.hexdigest())

我们可以使用多种参数运行:

$ python3 hashlib_new.py sha1

ea360b288b3dd178fe2625f55b2959bf1dba6eef

$ python3 hashlib_new.py sha256

3c887cc71c67949df29568119cc646f46b9cd2c2b39d456065646bc2fc09ffd8

$ python3 hashlib_new.py sha512

a7e53384eb9bb4251a19571450465d51809e0b7046101b87c4faef96b9bc904cf7f90
035f444952dfd9f6084eeee2457433f3ade614712f42f80960b2fca43ff

$ python3 hashlib_new.py md5

3f2fd2c9e25d60fb0fa5d593b802b7a8

增量更新

哈希计算器中的 update() 方法可以被重复调用。 每一次调用摘要都会根据额外的文字进行更新。增量更新比起读取整个文件进入内存中更加有效率,并且参数的结果是相同的。

hashlib_update.py

import hashlib

from hashlib_data import lorem

h = hashlib.md5()
h.update(lorem.encode('utf-8'))
all_at_once = h.hexdigest()

def chunkize(size, text):
    "Return parts of the text in size-based increments."
    start = 0
    while start < len(text):
        chunk = text[start:start + size]
        yield chunk
        start += size
    return

h = hashlib.md5()
for chunk in chunkize(64, lorem.encode('utf-8')):
    h.update(chunk)
line_by_line = h.hexdigest()

print('All at once :', all_at_once)
print('Line by line:', line_by_line)
print('Same        :', (all_at_once == line_by_line))

这个例子演示了如何在读取或以其他方式生成数据时增量更新摘要。

$ python3 hashlib_update.py

All at once : 3f2fd2c9e25d60fb0fa5d593b802b7a8
Line by line: 3f2fd2c9e25d60fb0fa5d593b802b7a8
Same        : True

扩展阅读

本文章首发在 LearnKu.com 网站上。

本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

原文地址:https://learnku.com/docs/pymotw/hashlib-...

译文地址:https://learnku.com/docs/pymotw/hashlib-...

上一篇 下一篇
讨论数量: 0
发起讨论 只看当前版本


暂无话题~