Perl下取得文件MD5校验码
2013-06-06 14:50:50 阿炯

本站赞助商链接,请多关照。 Perl支持众多文件校验,md5只是其中的一种,本文介绍一些常用的用于计算文件校验和的模块。
---------------
Digest::MD5核心模块
这是perl md5摘要算法的核心模块,包含了较多的函数,能适用于多数计算环境。

use Digest::MD5 qw(md5 md5_hex);
my $file_name=shift @ARGV;
my $hash;
{
 local $/ = undef;
 open FILE, "$file_name";
 binmode FILE;
 my $data = <FILE>;
 close FILE;
 $hash = md5_hex($data);
}

or you could use the OO interface:
my $file_name=shift @ARGV;
open FILE, "$file_name";

my $ctx = Digest::MD5->new;
$ctx->addfile (*FILE);
my $hash = $ctx->hexdigest;
close (FILE);

print $hash,"\n";

---------------
使用File::Slurp模块来与Digest::MD5相配合

#!/usr/bin/perl
use Digest::MD5 qw(md5_hex);
use File::Slurp;

my ($input) = @ARGV;
write_file "$input.md5", md5_hex(scalar read_file $input, binmode => ':raw'), "\n";

-----------------
Digest::file核心模块
Digest::file - Calculate digests of files,比Digest::MD5要简单些,当然也更专一,专用于计算文件的消息摘要。
use Digest::file qw(digest_file_hex);
 for (@ARGV) {
  print digest_file_hex($_, "MD5"), "  $_\n";
}

---------------
Digest::MD5::File
使用它可以计算出文件,目录下的所有文件,url的md5校验和。由于它没有列入到核心模块中,因此需要通过cpan进行安装后可用,是一个专用于计算文件消息摘要并有较大的适用范围的模块。

use Digest::MD5::File qw( file_md5_hex );
my $md5 = file_md5_hex( $some_file_name );

-----------------
与crc32算法相比较
For just comparing files, it might be enough to do a CRC32 and use this along with the file size. This has the added advantage of allowing quick scans through ZIP files for dupes as well (using Archive::Zip of course) because ZIP files already have crc32 values in them.

use strict;
use IO::File;
use Compress::Zlib ();
use Digest::MD5;
use Benchmark;
use constant BUFSIZE => 32768;

sub crc32{
 my $fh = shift;
 binmode($fh);
 sysseek($fh, 0, 0); # rewind
 my $buffer = ' ' x BUFSIZE;
 my $crc = 0;
 while ($fh->sysread($buffer, BUFSIZE)){
  $crc = Compress::Zlib::crc32($buffer, $crc);
 }
 return $crc;
}

sub md5{
 my $fh = shift;
 seek($fh, 0, 0); # rewind
 my $md5 = Digest::MD5->new();
 $md5->addfile($fh);
 return $md5->digest;
}

foreach my $file (@ARGV){
 my $fh = IO::File->new($file);
 binmode($fh);
 next if !defined($fh);
 Benchmark::cmpthese(-10,{
  "crc32 $file", sub { crc32($fh) },
  "md5 $file", sub { md5($fh) }
 });
}
--------------------
而对于普通文件来说,使用md5的要更好一些。