I tried this:
sub checksum { my $file = shift || return; my $md5 = Digest->new("MD5"); my $sha = Digest->new("SHA-256"); open my $fh, $file or die "Can't checksum file: $!"; binmode($fh); return ( MD5 => $md5->addfile($fh)->hexdigest(); SHA256 => $sha->addfile($fh)->hexdigest(); ); }
and then compared the output agaisnt checksums generated by FreeBSDs md5/sha256 utilities (they are actually the same program). The MD5 matched perfectly, but the SHA256 were different.
After much thinking, I figured it out....
sub checksum { my $file = shift || return; my $md5 = Digest->new("MD5"); my $sha = Digest->new("SHA-256"); open my $fh, $file or die "Can't checksum file: $!"; binmode($fh); my $mh = $md5->addfile($fh)->hexdigest(); seek($fh, 0, 0); # <----- you've got to rewind it to the start of the file before the next I/O my $sh = $sha->addfile($fh)->hexdigest(); return ( MD5 => $mh, SHA256 => $sh, ); }
The thing that really irks me, I was wondering if the Digest:: classes would be so nice, as to rewind the file handle when they were done, but I think that idea occured to me about 4 hours ago, lool. Actually, if I've got to rewind the fscking handle between objects, I may as well just walk the file and append the data to each as we go... then get the digests.
I really need more sleep....
EDIT: Take III
=pod internal checksum FILENAME Open filename, and return a hash containing ALGORITHM => check sum key/value pairs, for each algorithm supported. Both MD5 and SHA256 will always be supported. =cut sub checksum($) { my $file = shift || return; my $md5 = Digest->new("MD5"); my $sha = Digest->new("SHA-256"); open my $fh, $file or die "Can't checksum file: $!"; binmode($fh); # suck the file, and Digest::add it. We would have to parse # the entire file per object, and seek to 0,0 between calls other wise. while (my $ln = <$fh>) { $md5->add($ln); $sha->add($ln); } close $fh; return ( MD5 => $md5->hexdigest(), SHA256 => $sha->hexdigest(), ); }
No comments:
Post a Comment