我使用过hashlib(它取代了Python 2.6/3.0中的md5),如果我打开一个文件并将其内容放在hashlib.md5()函数中,它工作得很好。
问题是对于非常大的文件,它们的大小可能超过RAM大小。
如何在不将整个文件加载到内存的情况下获得文件的MD5哈希值?
我使用过hashlib(它取代了Python 2.6/3.0中的md5),如果我打开一个文件并将其内容放在hashlib.md5()函数中,它工作得很好。
问题是对于非常大的文件,它们的大小可能超过RAM大小。
如何在不将整个文件加载到内存的情况下获得文件的MD5哈希值?
当前回答
你需要以合适大小的块读取文件:
def md5_for_file(f, block_size=2**20):
md5 = hashlib.md5()
while True:
data = f.read(block_size)
if not data:
break
md5.update(data)
return md5.digest()
注意:确保你用'rb'打开你的文件-否则你会得到错误的结果。
所以要在一种方法中完成所有的事情-使用如下的方法:
def generate_file_md5(rootdir, filename, blocksize=2**20):
m = hashlib.md5()
with open( os.path.join(rootdir, filename) , "rb" ) as f:
while True:
buf = f.read(blocksize)
if not buf:
break
m.update( buf )
return m.hexdigest()
上面的更新是基于Frerich Raabe提供的评论——我测试了一下,发现在我的Python 2.7.2 Windows安装上是正确的
我用jacksum工具反复核对了结果。
jacksum -a md5 <filename>
其他回答
Bastien Semene的代码的混合,考虑了Hawkwing关于通用哈希函数的评论…
def hash_for_file(path, algorithm=hashlib.algorithms[0], block_size=256*128, human_readable=True):
"""
Block size directly depends on the block size of your filesystem
to avoid performances issues
Here I have blocks of 4096 octets (Default NTFS)
Linux Ext4 block size
sudo tune2fs -l /dev/sda5 | grep -i 'block size'
> Block size: 4096
Input:
path: a path
algorithm: an algorithm in hashlib.algorithms
ATM: ('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512')
block_size: a multiple of 128 corresponding to the block size of your filesystem
human_readable: switch between digest() or hexdigest() output, default hexdigest()
Output:
hash
"""
if algorithm not in hashlib.algorithms:
raise NameError('The algorithm "{algorithm}" you specified is '
'not a member of "hashlib.algorithms"'.format(algorithm=algorithm))
hash_algo = hashlib.new(algorithm) # According to hashlib documentation using new()
# will be slower then calling using named
# constructors, ex.: hashlib.md5()
with open(path, 'rb') as f:
for chunk in iter(lambda: f.read(block_size), b''):
hash_algo.update(chunk)
if human_readable:
file_hash = hash_algo.hexdigest()
else:
file_hash = hash_algo.digest()
return file_hash
import hashlib,re
opened = open('/home/parrot/pass.txt','r')
opened = open.readlines()
for i in opened:
strip1 = i.strip('\n')
hash_object = hashlib.md5(strip1.encode())
hash2 = hash_object.hexdigest()
print hash2
如果不阅读完整的内容,就无法获得它的md5。但是您可以使用update函数逐块读取文件的内容。
m.update(一个);M.update (b)等价于M.update (a+b)。
我不确定这里是不是有点太小题大做了。我最近在MySQL中遇到了md5和文件存储为blob的问题,所以我尝试了各种文件大小和简单的Python方法,即:
FileHash = hashlib.md5(FileData).hexdigest()
在2 KB到20 MB的文件大小范围内,我没有检测到任何明显的性能差异,因此不需要“块”散列。无论如何,如果Linux必须转到磁盘上,它可能至少会做得和普通程序员避免这样做的能力一样好。碰巧的是,这个问题与md5无关。如果您正在使用MySQL,不要忘记已经存在的md5()和sha1()函数。
我认为下面的代码更python化:
from hashlib import md5
def get_md5(fname):
m = md5()
with open(fname, 'rb') as fp:
for chunk in fp:
m.update(chunk)
return m.hexdigest()