0

我正在编写一个使用 File::Find 来索引网络文件系统的 Perl 脚本(在 Windows 中)。它工作得很好,但是爬取文件系统需要很长时间。我认为在遍历目录之前以某种方式获取目录的校验和会很好,并且校验和与之前运行的校验和相匹配,不要遍历目录。这将消除大量处理,因为此文件系统上的文件不会经常更改。

在我的 AIX 机器上,我使用以下命令:

csum -h MD5 /directory

它返回如下内容:

5cfe4faf4ad739219b6140054005d506  /directory

该命令花费的时间很少:

time csum -h MD5 /directory
5cfe4faf4ad739219b6140054005d506  /directory

real    0m0.00s
user    0m0.00s
sys     0m0.00s

我已经在 CPAN 中搜索了可以执行此操作的模块,但看起来所有模块都会为我提供目录中每个文件的 MD5sum,而不是目录本身。

有没有办法在 Perl 中获取目录的 MD5sum,甚至在 Windows 中,因为我可以从 Perl 调用 Win32 命令?

提前致谢!

4

5 回答 5

3

您可以只读取文件和文件夹的最后修改日期吗?这肯定会比构建 MD5 更快吗?

于 2009-05-26T16:02:35.740 回答
2

为了获得校验和,您必须读取文件,这意味着您需要遍历文件系统,这会使您回到您试图摆脱的同一条船上。

于 2009-05-26T16:00:46.320 回答
1

据我所知,您无法获得目录的 md5。当您提供目录时,其他系统上的 md5sum 会抱怨。csum 很可能会为您提供顶级目录的目录文件内容的哈希,而不是遍历树。

您可以通过执行以下操作获取文件的修改时间并按照您的喜好对它们进行散列:

sub dirModified($){
    my $dir = @_[0];
    opendir(DIR, "$dir");
    my @dircontents = readdir(DIR);
    closedir(DIR);

    foreach my $item (@dircontents){
        if( -f $item ){
            print -M $item . " : $item - do stuff here\n";
        } elsif( -d $item && $item !~ /^\.+$/ ){
            dirModified("$dir/$item");
        }
    }
}

是的,它需要一些时间来运行。

于 2009-05-26T16:16:46.897 回答
1

除了其他好的答案,让我补充一下:如果你想要一个校验和,那么请使用校验和算法而不是(损坏的!散列函数

我认为您不需要文件索引器中的加密安全哈希函数——相反,您需要一种方法来查看目录列表中是否有更改,而无需存储整个列表。校验和算法就是这样做的:当输入改变时,它们会返回不同的输出。他们可能会做得更快,因为它们比散列函数更简单。

确实,用户可以以校验和无法发现的方式更改目录。但是,用户将不得不像这样故意更改文件名,因为文件名的正常更改将(很有可能)给出不同的校验和。那么有必要防范这种“攻击”吗?

人们应该始终考虑每次攻击的后果并选择适当的工具。

于 2009-06-03T22:26:08.113 回答
0

如果您有兴趣,我在 python 中做了其中之一:

http://akiscode.com/articles/sha-1directoryhash.shtml

于 2009-10-30T07:36:15.607 回答