什么哈希 (Python 3 hashlib) 产生文件内容的可移植哈希?

What hash (Python 3 hashlib) yields a portable hash of file contents?

我想计算文件内容(的序列)的哈希值(其长度可以是任意数字位,因此不一定是 trendy 八的倍数)并将该文件与哈希值一起发送给朋友。我的朋友应该能够从文件内容中计算出相同的哈希值。我想用 Python 3 来计算散列,但是我的朋友不能用 Python 3 (因为我要等到明年才能发送文件,到那时 Python 3会过时,他会想使用 Python++ 或其他)。我能保证的是,我的朋友会知道如何从数学意义上计算散列值——他可能不得不在 MIX 机器的实现中将自己的代码写入 运行(这他会知道该怎么做。

我使用什么哈希值,更重要的是,我使用什么哈希值?例如,我是否将 read 返回的 str 散列为 text?我是否对从 binary read 返回的一些 bytes-like 对象进行哈希处理?如果文件有奇怪的行尾标记怎么办?我是否先填充尾端以便我散列的东西大小合适?

import hashlib
FILENAME = "filename"
# Now, what?

我说“sequence of bits因为不是所有的计算机都是基于8位字节的,所以说“sequence of bits” bytes”因此太含糊了。例如GreenArrays, Inc. has designed a supercomputer on a chip,其中每台计算机都有18-bit(十八位)字(这些字用于编码native指令时,由三个5-bit的“字节”和一个3-bit的字节组成每个)。我还了解到,在 1970 年代之前,使用了各种字节大小。尽管 8 位字节可能是最常见的选择,并且在某种意义上可能是最佳选择,但每个字节 8 位的选择是任意的。

另请参阅

首先,Python中的hash()函数与一般的加密散列函数不同。区别如下:

hash()

A hash is an fixed sized integer that identifies a particular value. Each value needs to have its own hash, so for the same value you will get the same hash even if it's not the same object.

Note that the hash of a value only needs to be the same for one run of Python. In Python 3.3 they will in fact change for every new run of Python

What does hash do in python?

加密哈希函数

A cryptographic hash function (CHF) is a mathematical algorithm that maps data of an arbitrary size (often called the "message") to a bit array of a fixed size

It is deterministic, meaning that the same message always results in the same hash.

https://en.wikipedia.org/wiki/Cryptographic_hash_function


现在让我们回到你的问题:

I would like to compute the hash of the contents (sequence of bits) of a file (whose length could be any number of bits, and so not necessarily a multiple of the trendy eight) and send that file to a friend along with the hash-value. My friend should be able to compute the same hash from the file contents.

您正在寻找的是加密散列函数之一。通常,要计算文件哈希,会使用 MD5、SHA-1、SHA-256。您想要以 binary 格式打开文件并对二进制位进行哈希处理,最后对其进行消化并以十六进制形式进行编码。

import hashlib

def calculateSHA256Hash(filePath):
    h = hashlib.sha256()
    with open(filePath, "rb") as f:
        data = f.read(2048)
        while data != b"":
            h.update(data)
            data = f.read(2048)
    return h.hexdigest()

print(calculateSHA256Hash(filePath = 'Whosebug_hash.py'))

上面的代码将自己作为输入,因此它为自己生成了一个 SHA-256 哈希值,即 610e15155439c75f6b63cd084c6a235b42bb6a54950dcb8f2edab45d0280335e。只要不更改代码,这就会保持一致。

另一个例子是对内容为 Helloworld.

的 txt 文件 test.txt 进行哈希处理

这只需将代码的最后一行更改为“test.txt”

print(calculateSHA256Hash(filePath = 'text.txt'))

这给出了 5ab92ff2e9e8e609398a36733c057e4903ac6643c646fbd9ab12d0f6234c8daf 的 SHA-256 散列。

在查看了 SHA-256 的 standard 之后,我找到了 sha256hexdigestFromFile,替代了@Lincoln Yan 的 calculateSHA256Hash

这也是对我关于 2048 的评论的回应。

def sha256hexdigestFromFile(filePath, blocks = 1):
    '''Return as a str the SHA-256 message digest of contents of
    file at filePath.
        Reference: Introduction of NIST (2015) Secure Hash
    Standard (SHS), FIPS PUB 180-4.  DOI:10.6028/NIST.FIPS.180-4
    '''
    assert isinstance(blocks, int) and 0 < blocks, \
            'The blocks argument must be an int greater than zero.'
    with open(filePath, 'rb') as MessageStream:
        from hashlib import sha256
        from functools import reduce
        def hashUpdated(Hash, MESSAGE_BLOCK):
            Hash.update(MESSAGE_BLOCK)
            return Hash
        def messageBlocks():
            'Return a generator over the blocks of the MessageStream.'
            WORD_SIZE, BLOCK_SIZE = 4, 512 # PER THE SHA-256 STANDARD
            BYTE_COUNT = WORD_SIZE * BLOCK_SIZE * blocks
            yield MessageStream.read(BYTE_COUNT)
        return reduce(hashUpdated, messageBlocks(), sha256()).hexdigest()