繁体   English   中英

在python中为大文件创建校验和的最快方法

[英]the fastest way to create checksum for large files in python

我需要跨网络传输大文件,需要每小时为它们创建校验和。 所以产生校验和的速度对我来说至关重要。

不知怎的,我不能让zlib.crc32和zlib.adler32在Windows XP Pro 64bit机器上使用大于4GB的文件。 我怀疑我在这里达到了32位的限制? 使用hashlib.md5我可以得到一个结果,但问题是速度。 为4.8GB文件生成md5大约需要5分钟。 任务管理器显示该进程仅使用一个核心。

我的问题是:

  1. 有没有办法让crc适用于大文件? 我更喜欢使用crc而不是md5
  2. 如果没有那么有没有办法加快md5.hexdigest()/ md5.digest? 或者在这种情况下任何hashlib hexdigest / digest? 可能将其拆分为多线程进程? 我怎么做?

PS:我正在开发类似于“资产管理”系统的东西,有点像svn,但资产包括大型压缩图像文件。 文件有微小的增量变化。 检测变化和错误检测需要散列/校验和。

这是一个算法选择问题 ,而不是库/语言选择问题!

主要有两点需要考虑:

  • 磁盘I / O会对整体性能产生多大影响?
  • 错误检测功能的预期可靠性是多少?

显然,第二个问题的答案是“ 允许一些假阴性 ”,因为相对于4Gb消息, 任何 32位散列的可靠性,即使在中等噪声频道中,也不会是绝对的。

假设可以通过多线程改进I / O,我们可以选择不需要对完整消息进行顺序扫描的哈希。 相反,我们可以并行处理文件,散列各个部分并组合散列值或附加散列值,以形成更长,更可靠的错误检测设备。

下一步可能是将这种文件处理形式化为有序部分,并将其作为传输(在接收者端重新粘合在一起)。 这种方法,以及有关文件生成方式的附加信息(例如,它们可能通过追加,例如日志文件进行排他性修改)甚至可以允许限制所需的哈希计算量。 这种方法增加的复杂性需要加权,以满足快速CRC计算的需求。

附注:Alder32 不限于消息大小低于特定阈值。 它可能只是zlib API的限制。 (顺便说一句,我发现关于zlib.adler32的参考使用了一个缓冲区,而且......在我们的大量消息的上下文中要避免这种方法,支持流式处理:从文件中读取一些,计算,重复。 。)

首先,任何CRC算法都没有固有的东西阻止它们处理任意长度的数据(但是,特定的实现可能会施加一个限制)。

但是,在文件同步应用程序中,这可能无关紧要,因为您可能不希望在文件变大时散列整个文件,无论如何都只是块。 如果散列整个文件,并且每端的散列不同,则必须复制整个文件。 如果您散列固定大小的块,那么您只需要复制散列已更改的块。 如果对文件的大多数更改都是本地化的(例如数据库),那么这可能需要更少的复制(并且它更容易在多个核心上的每个块计算中传播)。

至于哈希算法本身,基本的权衡是速度与缺少冲突(两个不同的数据块产生相同的哈希)。 CRC-32速度很快,但只有2 ^ 32个唯一值,可能会出现冲突。 MD5要慢得多,但是有2 ^ 128个唯一值,因此几乎从未见过碰撞(但理论上仍然可能)。 较大的哈希值(SHA1,SHA256,...)具有更多独特的值,但速度更慢:我怀疑你需要它们:你担心意外碰撞,不像数字签名应用程序,你有意担心(恶意的设计碰撞。

听起来你正在尝试做一些与rsync实用程序非常相似的事情。 你能用到rsync吗?

您可能在XP中遇到文件的大小限制。 64位为您提供更多的寻址空间(每个应用程序移除2GB(左右)寻址空间),但可能对文件大小问题没有任何作用。

由于MD5的本质,你不可能使用多个核心来计算大文件的MD5哈希:它希望消息以块的形式分解并以严格的顺序输入散列函数。 但是,您可以使用一个线程将文件读入内部队列,然后在单独的线程中计算哈希值。 我不认为这会给你带来任何显着的性能提升。

处理大文件需要这么长时间的事实可能是由于“无缓冲”读取。 尝试一次读取16 Kb,然后将内容以块的形式提供给散列函数。

md5本身不能并行运行。 但是你可以在部分(并行)中md5文件,并获取哈希列表的md5。

但是,假设散列不受IO限制,我怀疑它是。 正如Anton Gogolev建议的那样 - 确保你正在有效地阅读文件(以2个大块的力量)。 完成后,请确保文件没有碎片。

对于新项目,还应选择sha256之类的散列而不是md5。

对于4Gb文件,zlib校验和是否比md5快得多?

你有没有试过crc-generator模块?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM