use strict;
use warnings;
use Fcntl ':seek';
use constant CHUNK => 65536;
sub calc {
my $file = shift or die "no filename given\n";
my $hash = -s $file;
my $chunk = CHUNK;
$hash < $chunk and die "$file is too small ($hash bytes < $chunk)\n";
open my $in, '<', $file or die "Cannot open $file for input: $!\n";
local $/ = \$chunk;
$hash += ord($_) for split //, readline($in);
seek($in, SEEK_END, -$chunk);
$hash += ord($_) for split //, readline($in);
close $in;
return sprintf '%016x', $hash;
}
print calc($_), "\t$_\n" for @ARGV;
####
use strict;
use warnings;
use Fcntl ':seek';
use constant CHUNK => 65536;
sub calc {
my $file = shift or die "no filename given\n";
my $hash = -s $file;
my $chunk = CHUNK;
$hash < $chunk and die "$file is too small ($hash bytes < $chunk)\n";
open my $in, '<', $file or die "Cannot open $file for input: $!\n";
local $/ = \$chunk;
$hash += $_ for unpack 'N*' , readline($in);
seek($in, SEEK_END, -$chunk);
$hash += $_ for unpack 'N*' , readline($in);
close $in;
return sprintf '%016x', $hash;
}
my $test = 'test.deleteme';
open my $out, '>', $test;
print $out ' ' x (65536*4);
close $out;
print calc($test), $/;
unlink $test;
####
use strict;
use warnings;
use Fcntl ':seek';
use bigint;
use constant CHUNK => 65536;
sub calc {
my $file = shift or die "no filename given\n";
my $hash = -s $file;
my $chunk = CHUNK;
$hash < $chunk and die "$file is too small ($hash bytes < $chunk)\n";
open my $in, '<', $file or die "Cannot open $file for input: $!\n";
local $/ = \$chunk;
for my $quad (unpack 'q*' , readline($in)) {
$hash += $quad;
$hash &= 2 ** 64 - 1;
}
seek($in, SEEK_END, -$chunk);
for my $quad (unpack 'q*' , readline($in)) {
$hash += $quad;
$hash &= 2 ** 64 - 1;
}
close $in;
return sprintf '%016x', $hash;
}
open my $out, '>', 'test.deleteme';
print $out ' ' x (65536*4);
close $out;
print calc('test.deleteme'), $/;