每週一個 Python 模組 | hashlib

yongxinz發表於2019-02-01

專欄地址:每週一個 Python 模組

hashlib 模組定義了用於訪問不同加密雜湊演算法的 API。要使用特定的雜湊演算法,需要先用適當的建構函式或new()建立雜湊物件。然後,無論使用何種演算法,物件都使用相同的 API。

雜湊演算法

由於hashlib 受 OpenSSL “支援”,因此該庫提供的所有演算法都可用,包括:

  • MD5
  • SHA1
  • SHA224
  • SHA256
  • SHA384
  • SHA512

有些演算法可用於所有平臺,有些演算法依賴於底層庫。對於每個列表,分別檢視 algorithms_guaranteedalgorithms_available 函式。

import hashlib


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

# output
# Guaranteed:
# blake2b, blake2s, md5, sha1, sha224, sha256, sha384, sha3_224,
# sha3_256, sha3_384, sha3_512, sha512, shake_128, shake_256
# 
# Available:
# BLAKE2b512, BLAKE2s256, MD4, MD5, MD5 - SHA1, RIPEMD160, SHA1,
# SHA224, SHA256, SHA384, SHA512, blake2b, blake2b512, blake2s,
# blake2s256, md4, md5, md5 - sha1, ripemd160, 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()

import hashlib

from hashlib_data import lorem

h = hashlib.md5()
h.update(lorem.encode('utf-8'))
print(h.hexdigest())	# 3f2fd2c9e25d60fb0fa5d593b802b7a8
複製程式碼

此例使用 hexdigest() 方法而不是 digest(),因為輸出已格式化,因此可以清晰地列印。如果二進位制摘要值可以接受,請使用digest()

SHA1示例

SHA1 摘要以相同的方式計算。

import hashlib

from hashlib_data import lorem

h = hashlib.sha1()
h.update(lorem.encode('utf-8'))
print(h.hexdigest())	# ea360b288b3dd178fe2625f55b2959bf1dba6eef
複製程式碼

摘要值在此示例中是不同的,因為演算法從 MD5 更改為 SHA1。

按名稱建立雜湊

有時,在字串中按名稱引用演算法比通過直接使用建構函式更方便。例如,將雜湊型別儲存在配置檔案中。在這種情況下,用 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())

# output
# $ 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() 可以重複呼叫雜湊計算器的方法。每次,摘要都會根據輸入的附加文字進行更新。逐步更新比將整個檔案讀入記憶體更有效,併產生相同的結果。

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)	# All at once : 3f2fd2c9e25d60fb0fa5d593b802b7a8
print('Line by line:', line_by_line)  # Line by line: 3f2fd2c9e25d60fb0fa5d593b802b7a8
print('Same        :', (all_at_once == line_by_line))	# Same        : True
複製程式碼

相關文件:

pymotw.com/3/hashlib/i…

相關文章