#!/usr/bin/perl use strict; use warnings; my $BUFFSIZE = 4096 *1; sub Checksum { my ($FileName, $Start_byte, $Size) = @_; open (my $fh, '<', $FileName) or die "unable to open $FileName for read $!"; binmode $fh; #This is truly bizarre! Checksum does not start at beginning of file! # seek ($fh, $Start_byte, 0) or die "Cannot seek to $Start_byte on $FileName $!"; my $check_sum =0; # Allow for checkum only on a "window" of the input file, i.e. $Size may be # much smaller than size_of_file - start_byte! Another Bizarre requirement!! while ($Size >0) { my $n_byte_request = ($BUFFSIZE > $Size) ? $Size : $BUFFSIZE; my $n_bytes_read = read($fh, my $buff, $n_byte_request); die "file system error binary read for $FileName" unless defined $n_bytes_read; die "premature EOF on $FileName checksum block size too big for actual file" if ($n_bytes_read < $n_byte_request); my @bytes = unpack('C*', $buff); #input string of data are 8 bit unsigned ints # check_sum is at least a 32 bit signed int. masking to 16 bits # after every add probably not needed, but maybe. $check_sum += $_ for @bytes; $Size -= $n_bytes_read; } close $fh; $check_sum &= 0xFFFF; #Truncate to 16 bits, probably have to do this more often... return $check_sum; } my $chk = Checksum('BinaryCheckSum.pl', 0,2); print $chk; #prints 68 decimal, 0x23 + 0x21, "#!"