TeamViterbi has asked for the wisdom of the Perl Monks concerning the following question:

Hey everybody, I'm having difficulty using the read command to perform a checksum operation. Whenever I print the final checksum, the result always returns FFFFFFFF, and I know thats not the checksum.
Code: #!/usr/bin/perl -w use strict; use FileHandle; use warnings; my $data = "file.bin"; my $buffer; my $string; my $n = 0; my $checksum = 0; my $num = 0; my $str = unpack("B32", pack("N", shift)); my $bits = 4; my $decimal; open FILE, $data or die $!; binmode FILE; while (($n = read FILE, $buffer, 4)) { $decimal = unpack("N", pack("B32", $buffer)); {$checksum = $checksum + $decimal; #$num = $num + $bits;} #print "1. $num\n"; print "2. $decimal\n"; #print "3. $n bytes read\n"; print "4. $checksum \n"; } $checksum = $checksum & 0xFFFFFFFF;
Basically, I'm trying to read a binary file 32 bits at a time by unpacking them into decimal and then adding them. Furthermore, I am trying to use the $checksum & 0xFFFFFFFFF command to restrain the checksum to 32 bits. Also, just ignore the commented out stuff, I was using it for my own testing. Any assistance would be greatly appreciated.

Replies are listed 'Best First'.
Re: Difficulty restraining read function to 32 bits
by ikegami (Patriarch) on Jul 15, 2009 at 23:24 UTC
    Your very attempt to limit $checksum to 32-bits is causing an overflow. & forces its arguments into native ints, and the pre-limiting value of $checksum doesn't fit into one.
    $ perl -le'print $ARGV[0] & 0xFFFFFFFF' 1000000000 1000000000 $ perl -le'print $ARGV[0] & 0xFFFFFFFF' 10000000000 4294967295

    Use a floating point operation.

    Replace
    $checksum = $checksum & 0xFFFFFFFF;
    with
    $checksum %= 2**32;

      Thanks for the quick reply ikegami. I made the replacement, but the checksum that I'm getting is just a bit shy (1 million short) of the checksum that I am trying to get (I already know the checksum). Lets say that there are 31 bits left over in the file, would the script read it and add it? or would it be 0ed out? Thanks again for your help.

        Lets say that there are 31 bits left over in the file

        Let's say 24 bits (3 bytes). It's "hard" to store a fraction number of a bytes in a file.

        read would return three bytes instead of four for the last read.

        jwkrahn points out a real problem too.

Re: Difficulty restraining read function to 32 bits
by jwkrahn (Abbot) on Jul 16, 2009 at 00:05 UTC
    while (($n = read FILE, $buffer, 4)) { $decimal = unpack("N", pack("B32", $buffer));

    $buffer gets a four byte (32 bit) binary string read from the file and then you convert that with pack("B32", $buffer)???   That pack is not doing what you seem to think it is doing.   You just need the unpack:

    $decimal = unpack 'N', $buffer;