python获取服务器文件md5,获取的在Python大文件的MD5哈希获取的在Python大文件的MD5哈希(Get MD5 has...

夏骞尧
2023-12-01

我已经使用hashlib(这在Python 2.6 / 3.0替换MD5),如果我打开一个文件,并把它的内容在它工作得很好hashlib.md5()函数。

问题是与它们的大小可能会超过RAM容量非常大的文件。

如何获得文件的MD5哈希值,而无需加载整个文件到内存?

Answer 1:

打破文件到128字节的块,并连续地使用它们馈送到MD5 update()

这需要的事实,MD5具有128字节的摘要块的优势。 基本上,当MD5 digest() s文件,这正是它在做什么。

如果你确保你释放在每次迭代的内存(即无法读取整个文件到内存),这应采取不超过128字节的内存。

一个例子是读取数据块,像这样:

f = open(fileName)

while not endOfFile:

f.read(128)

Answer 2:

你需要读取合适大小的块中的文件:

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拉贝提出的意见 - 我试用了一下,发现它是正确的我的Python 2.7.2 windows安装

我反复核对使用“jacksum”工具的结果。

jacksum -a md5

http://www.jonelo.de/java/jacksum/

Answer 3:

如果你关心更Python(无“而真正的”)的读取文件检查此编码方式:

import hashlib

def checksum_md5(filename):

md5 = hashlib.md5()

with open(filename,'rb') as f:

for chunk in iter(lambda: f.read(8192), b''):

md5.update(chunk)

return md5.digest()

需要注意的是ITER()FUNC需要为返回的迭代以EOF停止空字节串,因为read()返回B“”(不只是“”)。

Answer 4:

这里是我的@Piotr Czapla的方法的版本:

def md5sum(filename):

md5 = hashlib.md5()

with open(filename, 'rb') as f:

for chunk in iter(lambda: f.read(128 * md5.block_size), b''):

md5.update(chunk)

return md5.hexdigest()

Answer 5:

使用这个线程多评论/答案,这里是我的解决方案:

import hashlib

def md5_for_file(path, block_size=256*128, hr=False):

'''

Block size directly depends on the block size of your filesystem

to avoid performances issues

Here I have blocks of 4096 octets (Default NTFS)

'''

md5 = hashlib.md5()

with open(path,'rb') as f:

for chunk in iter(lambda: f.read(block_size), b''):

md5.update(chunk)

if hr:

return md5.hexdigest()

return md5.digest()

这是“Python的”

这是一个功能

它避免了隐含值:总是喜欢那些明确。

它允许(非常重要)表演的优化

最后,

-这已经由一个社区而建,感谢大家的意见/建议。

Answer 6:

一个Python 2/3的便携式解决方案

计算校验(MD5,SHA1,等等),你必须以二进制方式打开该文件,因为你会总结字节值:

要py27 / PY3便携,你应该使用io包,就像这样:

import hashlib

import io

def md5sum(src):

md5 = hashlib.md5()

with io.open(src, mode="rb") as fd:

content = fd.read()

md5.update(content)

return md5

如果你的文件是大,你可能更喜欢通过块读取文件,以避免在内存中存储整个文件内容:

def md5sum(src, length=io.DEFAULT_BUFFER_SIZE):

md5 = hashlib.md5()

with io.open(src, mode="rb") as fd:

for chunk in iter(lambda: fd.read(length), b''):

md5.update(chunk)

return md5

这里的技巧是使用iter()函数使用Sentinel(空字符串)。

在这种情况下创建的迭代器将调用的问题o [lambda函数]不带参数为每个呼叫到其next()方法; 如果返回的值等于定点, StopIteration将提高,否则该值将被退回。

如果你的文件是非常大的 ,你可能还需要显示进度信息。 你可以通过调用一个回调函数,打印或记录计算的字节数:

def md5sum(src, callback, length=io.DEFAULT_BUFFER_SIZE):

calculated = 0

md5 = hashlib.md5()

with io.open(src, mode="rb") as fd:

for chunk in iter(lambda: fd.read(length), b''):

md5.update(chunk)

calculated += len(chunk)

callback(calculated)

return md5

Answer 7:

巴斯蒂安的代码义素混音称取约通用散列函数考虑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

Answer 8:

不能得到的,它是不阅读完整内容MD5。 但你可以使用更新功能块来读取文件中的内容块。

m.update(一); m.update(b)是相当于m.update(A + B)

Answer 9:

我认为下面的代码是更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()

Answer 10:

Django的接受的答案的执行情况:

import hashlib

from django.db import models

class MyModel(models.Model):

file = models.FileField() # any field based on django.core.files.File

def get_hash(self):

hash = hashlib.md5()

for chunk in self.file.chunks(chunk_size=8192):

hash.update(chunk)

return hash.hexdigest()

Answer 11:

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

Answer 12:

我不知道有是不是有点过分大惊小怪这里。 我最近有存储在MySQL斑点MD5和文件的问题,所以我尝试了各种文件大小和简单的Python的办法,即:

FileHash=hashlib.md5(FileData).hexdigest()

我可以检测与一系列文件没有明显的性能差异大小2K位为20MB,因此没有必要“块”的散列。 无论如何,如果Linux有去到磁盘上,它可能会做它至少和一般的程序员的保持它这样做的能力。 因为它发生,问题是无关MD5。 如果你使用MySQL,不要忘了MD5()和SHA1()函数已经存在。

文章来源: Get MD5 hash of big files in Python

 类似资料: