超大文件如何计算md5?
程序员文章站
2022-06-13 20:02:28
...
回复内容:
首先,至少没必要先把整个文件读到内存里。比如在 php 里,如果有人 md5(file_get_contents(big_file_name)) 就确实非常不妥当。因为 md5 是每 512 bit 作为一个 chunk 进行计算的。所以可以每次读取一部分的内容(最少 512 bit,比较合适是 st_blksize),进行那些 chunk 部分的计算,之后再读取下一部分内容继续计算。 MD5算法本身是分块的,其他很多类似的算法比如SHA-1也是的,所以可以支持流式计算,读一块算一块,最后再一次性生成完整hash,完全没有内存爆炸的可能。
大多数语言都会提供流式的HashAlgorithm的API的,php也提供了md5_file,而且查文档看它内部是流式的。 我之前的做法是取每100m的前1m作md5.然后整体再md5一次。感觉也是蛮萌的。时间少花了很多,暂时还未碰撞过。 简单先说下,md5是有规范的,提供了现成的算法(规范的名字就是md5算法。RFC 1321 The MD5 Message-Digest Algorithm),我们只需要翻译成c、java、python、js等等代码。
代码建议从网上找,没必要造*。
另外,下载个校验器,测试下代码正确性,之前踩过坑。。
http://www.freesoft.org/CIE/RFC/1321/ 据我猜测 各大网盘 TB级别 md5算法应该是这样的,楼上几位都说了文件md5是文件流分块算出来的,那么网盘想获得TB级别文件的md5就必须读取整个文件的文件流才能得到,但是这么做效率十分低下,运算时间是个问题。但是大家忽略了一个问题,文件在上传的过程也是分块上传的,这些上传的碎片其实也是文件流。那么可以把计算md5的时间分摊到每一个碎片上。这样每上传一个片段就计算一点等上传完成了,文件的md5也就算出来了。okTB级别MD5不是问题了。上传完成md5自然就出来了。 不知道我的猜测大家有其他看法没有。
刚才有仁兄提出都传完了就还怎么秒传。秒传最基本的是先要前端算出md5然后传给后端(可能需要更多种哈希值)我研究了很久前端没有办法秒内完成超大文件MD5的,现在用html5 的api 可以算出任意大小文件的 md5 但是耗时相当长。我没有解决办法。也没有想到那些网盘怎么在前端快速获取md5的。 有想方法或者感兴趣的可以加我QQ 122138299一起研究一下。最近正在做断点续传 和秒传的项目。 头、中、尾各取一段1M的数据来取md5。
上面是开玩笑,正确的答案是,没什么好办法,还是常规md5+缓存吧。 如果对一个1G大小的文件做md5,耗时是大概是什么级别的 http://www.atool.org/file_hash.php js写的文件hash,看他的代码,你就知道怎么计算大文件md5了…
肯定不是一次读进来,不然浏览器烂爆了… 这个问题其实可以参考各大网盘是怎么做的