【问题标题】:How to Calculate a Hash of a file that is 1 Terabyte and over?如何计算 1 TB 及以上文件的哈希?
【发布时间】:2014-05-08 14:50:02
【问题描述】:

所以,我有几个大约 1 TB 的系统备份映像文件, 我想快速计算它们中的每一个的哈希值(最好是 SHA-1)。

起初我尝试计算 md5 哈希值,2 小时过去了,但尚未计算哈希值(这对于高达 1TB 的大文件来说很明显)。

那么有没有可以快速散列 1TB 文件的程序/实现?

我听说过同时对部分文件进行哈希处理的 Tree-Hashing,但到目前为止我还没有找到任何实现。

【问题讨论】:

    标签: hash large-data


    【解决方案1】:

    如果你有一个 100 万 MB 的文件,并且你的系统可以以 100MB/s 的速度读取这个文件,那么

    • 1TB * 1000(TB/GB) = 1000GB
    • 1000GB * 1000(MB/GB) = 100 万 MB
    • 100 万 MB/100(MB/s) = 10000 秒
    • 10000s/3600(s/hr) = 2.77...小时
    • 因此,一个 100MB/s 系统的硬底是 2.77... 小时,甚至首先读取文件,甚至在计算哈希可能需要任何额外的总时间之前。

    您的期望可能不切实际 - 在您可以执行更快的文件读取之前,不要尝试计算更快的哈希值。

    【讨论】:

    • 你是对的,但我怀疑我的系统能否以 100MB/s 的速度读取文件 :( 是否有其他方法可以更快地读取文件?
    • 要更快地读取文件,您需要更快的存储空间,这主要意味着您将要花很多钱。在备份软件、RAIDSSD 或 RAID 中的 SSD、PCIe SSD 或 RAMDisk 中的多个磁盘上分割备份;一切都会奏效。或者,如果您使用的是开源备份软件,请让它在写入输出时计算哈希值。我不能改变物理定律!
    • 嗯,是的,看来这就是事实。但是,如果其他人想添加一些内容,我会在接受您的回答之前抽出一些时间。
    【解决方案2】:

    旧且已回答,但您可以尝试选择特定的文件块。

    我在某处找到了一个 perl 解决方案,它看起来很有效,代码不是我的:

    #!/usr/bin/perl
    
    use strict;
    use Time::HiRes qw[ time ];
    use Digest::MD5;
    
    sub quickMD5 {
        my $fh = shift;
        my $md5 = new Digest::MD5->new;
    
        $md5->add( -s $fh );
    
        my $pos = 0;
        until( eof $fh ) {
            seek $fh, $pos, 0;
            read( $fh, my $block, 4096 ) or last;
            $md5->add( $block );
            $pos += 2048**2;
        }
        return $md5;
    }
    
    open FH, '<', $ARGV[0] or die $!;
    printf "Processing $ARGV[0] : %u bytes\n", -s FH;
    
    my $start = time;
    my $qmd5 = quickMD5( *FH );
    printf "Partial MD5 took %.6f seconds\n", time() - $start;
    print "Partial MD5: ", $qmd5->hexdigest, "\n";
    

    基本上,该脚本在文件中的每 4MB 块的前 4KB 上执行 MD5(实际上原始的每 1MB 执行一次)。

    【讨论】:

    • 嗯,有趣的想法!但是,如果在 2MB 块的前 4KB 之后,只有一小部分文件损坏了,就会出现问题。但无论如何,这是我不知道的好东西!感谢分享!! :)
    • 我通常对 3.4TB 文件进行 md5 处理,并每天将其复制到外部存储。到现在为止,我并不感到意外,顺便说一句,标准 NAS 性能完整的 MD5,也给出了复制时间,对我来说不是一个选择!还要考虑你正在做超过 250000/300000 个数据块的 MD5,对于这么大的文件应该是可以接受的安全的。
    • 如何使用此脚本检查完整的文件系统并将结果写入文件而不是只检查一个文件?
    • 您只需要在外部调用它(即使用 bash 脚本)。现在无法编码,但是如果您将文件系统相关文件夹上的“查找”命令的输出通过管道传输到 perl 脚本应该可以解决问题。在您的 bash 脚本中,您应该有类似“find /folder/ -type f | xargs perl_script”的内容并将 a 重定向到日志文件。
    【解决方案3】:

    我建议您查看非加密哈希(例如:xxhashmurmur3),它们比 md5 快得多,当然直到您达到最大读取速度为止。

    【讨论】:

      猜你喜欢
      • 2011-11-05
      • 1970-01-01
      • 1970-01-01
      • 2011-07-30
      • 2023-03-14
      • 2017-09-23
      • 2016-06-23
      • 2015-12-18
      • 1970-01-01
      相关资源
      最近更新 更多