用Python散列文件

2024-04-29 20:24:16 发布

您现在位置:Python中文网/ 问答频道 /正文

我希望python读取到EOF,这样我就可以得到一个适当的散列,不管它是sha1还是md5。请帮忙。以下是我目前掌握的情况:

import hashlib

inputFile = raw_input("Enter the name of the file:")
openedFile = open(inputFile)
readFile = openedFile.read()

md5Hash = hashlib.md5(readFile)
md5Hashed = md5Hash.hexdigest()

sha1Hash = hashlib.sha1(readFile)
sha1Hashed = sha1Hash.hexdigest()

print "File Name: %s" % inputFile
print "MD5: %r" % md5Hashed
print "SHA1: %r" % sha1Hashed

Tags: the情况sha1md5hashlibprintmd5hasheof
3条回答

为了正确有效地计算文件的哈希值(在Python 3中):

  • 以二进制模式打开文件(即在文件模式中添加'b'),以避免字符编码和行尾转换问题。
  • 不要把完整的文件读入内存,因为那是浪费内存。相反,按顺序逐块读取并更新每个块的散列。
  • 消除双缓冲,即不使用缓冲IO,因为我们已经使用了最佳块大小。
  • 使用readinto()避免缓冲区搅动。

示例:

import hashlib

def sha256sum(filename):
    h  = hashlib.sha256()
    b  = bytearray(128*1024)
    mv = memoryview(b)
    with open(filename, 'rb', buffering=0) as f:
        for n in iter(lambda : f.readinto(mv), 0):
            h.update(mv[:n])
    return h.hexdigest()

我只建议:

def get_digest(file_path):
    h = hashlib.sha256()

    with open(file_path, 'rb') as file:
        while True:
            # Reading is buffered, so we can read smaller chunks.
            chunk = file.read(h.block_size)
            if not chunk:
                break
            h.update(chunk)

    return h.hexdigest()

所有其他的答案似乎都太复杂了。Python在读取时已经在缓冲了(以理想的方式,或者如果您有更多关于底层存储的信息,您可以配置该缓冲),因此最好是分块读取hash函数找到的理想值,这样可以加快计算hash函数的速度,或者至少减少计算hash函数所需的CPU。因此,与其禁用缓冲并试图自己模拟它,不如使用Python缓冲并控制应该控制的内容:数据使用者发现的理想值,散列块大小。

TL;DR使用缓冲区不使用大量内存。

我相信,当我们考虑使用非常大的文件的内存影响时,我们会找到问题的症结所在。我们不希望这个坏小子为了一个2G的文件而翻腾出2G的ram,所以,正如pasztorpisti所指出的,我们必须把那些大文件分成块来处理!

import sys
import hashlib

# BUF_SIZE is totally arbitrary, change for your app!
BUF_SIZE = 65536  # lets read stuff in 64kb chunks!

md5 = hashlib.md5()
sha1 = hashlib.sha1()

with open(sys.argv[1], 'rb') as f:
    while True:
        data = f.read(BUF_SIZE)
        if not data:
            break
        md5.update(data)
        sha1.update(data)

print("MD5: {0}".format(md5.hexdigest()))
print("SHA1: {0}".format(sha1.hexdigest()))

我们所做的是,当我们使用hashlib的便利的dandyupdate method时,我们正在更新这个坏男孩的64kb块散列。这样一来,我们使用的内存比一下子把这个家伙搞砸所需的2gb要少得多!

你可以用以下方法测试:

$ mkfile 2g bigfile
$ python hashes.py bigfile
MD5: a981130cf2b7e09f4686dc273cf7187e
SHA1: 91d50642dd930e9542c39d36f0516d45f4e1af0d
$ md5 bigfile
MD5 (bigfile) = a981130cf2b7e09f4686dc273cf7187e
$ shasum bigfile
91d50642dd930e9542c39d36f0516d45f4e1af0d  bigfile

希望能有帮助!

所有这些都在右边的链接问题中列出:Get MD5 hash of big files in Python


补遗!

一般来说,在编写python时,它有助于养成遵循pep-8的习惯。例如,在python中,变量通常是下划线分隔的,而不是camelCased。但那只是一种风格,没有人真正关心那些东西,除了那些不得不读糟糕的风格的人。。。可能是你从现在开始读这段代码。

相关问题 更多 >