为什么Python计算“hashlib.sha1”与文件中的“git hash-object”不同?

我正在尝试计算文件的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

他们怎么不一样? 我做错了什么,或者我可以忽略它们的区别?

git像这样计算哈希值:

 sha1("blob " + filesize + "\0" + data) 

参考

作为参考,这里是一个更简洁的版本:

 def sha1OfFile(filepath): import hashlib with open(filepath, 'rb') as f: return hashlib.sha1(f.read()).hexdigest() 

第二个想法:虽然我从来没有见过,但我认为有可能f.read()返回less于整个文件,或为一个多GB的文件,f.read()内存不足。 对于每个人的熏陶,让我们考虑如何解决这个问题:第一个解决scheme是:

 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() 

当然,谁来说我们可以存储一兆字节的string。 我们可能可以,但是如果我们在一个小巧的embedded式计算机上呢?

我希望我能想到一个更清洁的方式,保证不会在大量文件中耗尽内存,并且没有神奇的数字,并且能够执行原始简单的Pythonic解决scheme。