我正在尝试计算文件的SHA-1值。
我编造了这个剧本:
def hashfile(filepath):
sha1 = hashlib.sha1()
f = open(filepath, 'rb')
try:
sha1.update(f.read())
finally:
f.close()
return sha1.hexdigest()
对于特定文件,我得到这个哈希值:
8c3e109ff260f7b11087974ef7bcdbdc69a0a3b9
但是当我用git hash_object计算值时,我得到这个值:d339346ca154f6ed9e92205c3c5c38112e761eb7
他们怎么会有所不同?我做错了什么,或者我可以忽略差异?
答案 0 :(得分:51)
答案 1 :(得分:32)
供参考,这是一个更简洁的版本:
def sha1OfFile(filepath):
import hashlib
with open(filepath, 'rb') as f:
return hashlib.sha1(f.read()).hexdigest()
第二个想法:虽然我从未见过它,但我认为f.read()
有可能返回少于完整文件或少许千兆字节文件,因为f.read()用完了记忆对于每个人的启发,让我们考虑如何解决这个问题:第一个解决方法是:
def sha1OfFile(filepath):
import hashlib
sha = hashlib.sha1()
with open(filepath, 'rb') as f:
for line in f:
sha.update(line)
return sha.hexdigest()
但是,无法保证文件中出现'\n'
,因此for
循环将为我们提供以'\n'
结尾的文件块的事实可以为我们提供帮助我们原来遇到的同样问题。遗憾的是,我没有看到任何类似的Pythonic方法来尽可能大地迭代文件块,我认为这意味着我们遇到了while True: ... break
循环以及块大小的幻数:
def sha1OfFile(filepath):
import hashlib
sha = hashlib.sha1()
with open(filepath, 'rb') as f:
while True:
block = f.read(2**10) # Magic number: one-megabyte blocks.
if not block: break
sha.update(block)
return sha.hexdigest()
当然,谁能说我们可以存储一兆字节的字符串。我们可能会,但如果我们在一台小型嵌入式计算机上呢?
我希望我能想到一种更清洁的方式,保证不会在大量文件上耗尽内存,并且没有神奇的数字,并且与原始的简单Pythonic解决方案一样好。