如何计算 1 TB 及以上文件的哈希值?

问题描述 投票:0回答:3

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

起初我尝试计算 md5 哈希值,2 小时过去了,哈希值还没有计算出来(对于高达 1TB 的大文件来说这是显而易见的)。

那么有没有任何程序/实现可以快速哈希 1TB 文件?

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

hash large-data
3个回答
9
投票

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

  • 1TB * 1000(TB/GB) = 1000GB
  • 1000GB * 1000(MB/GB) = 100 万MB
  • 100万MB/100(MB/s)=1万秒
  • 10000 秒/3600(秒/小时)= 2.77...小时
  • 因此,即使在计算哈希可能需要额外的总时间之前,100MB/s 的系统也需要 2.77... 小时的硬底来读取文件。

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


7
投票

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

我在某处找到了一个 Perl 解决方案,它似乎很有效。 基本上,该脚本对文件中每个 4MB 块的前 4KB 执行 MD5。

请注意,因为这是对文件进行“采样”,所以它不是完整的证明,也就是说,如果每个 4MB 块的最后 8 个字节发生变化,它可能不会被这个哈希算法捕获(取决于最后一个块的大小)。

#!/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";

0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.