(1) Perl can calculate checksum for you, see unpack:
In addition to fields allowed in pack, you may prefix a field with a %<number> to indicate that you want a <number>-bit checksum of the items instead of the items themselves. Default is a 16-bit checksum. The checksum is calculated by summing numeric values of expanded values
As:
>perl -wE "say unpack '%8C*', qq(\x{01}\x{02}\x{ff})" 2
Here, I calculate 8-bit checksum only to demonstrate that "it works", you probably should write something like:
sysread ( $FileHandle, $Buffer, $Size, $ChecksumByteOffset ) or die; $Checksum = unpack '%C*', $Buffer;
Unless you need to read really huge chunks. But even then, read larger pieces than just byte by byte.
(2) Do you run your code under use warnings;? You should, to catch if not this, then possibly other, more dangerous errors.
>perl -wE "say 1 + unpack 'S', 0" Use of uninitialized value in addition (+) at -e line 1. 1
Though expected net result is correct, initial value of your accumulator is 0, i.e. too short string ("0") for first call to unpack to produce anything but undef in scalar context.
Hm-m, documentation says actually:If there are more pack codes or if the repeat count of a field or a group is larger than what the remainder of the input string allows, the result is not well defined: the repeat count may be decreased, or unpack may produce empty strings or zeros, or it may raise an exception.
(3) Unless you use recipe (1) (or use it in modified form, reading chunk by chunk) I'd suggest using modulo arithmetic directly instead of tricks with packing:
use strict; use warnings; use Benchmark 'cmpthese'; cmpthese -3, { packing => sub { my $sum = 0; $sum = unpack("S", pack("S", $sum + +$_)) for 0..1e6 }, modulo => sub { my $sum = 0; $sum = ($sum + $_) % 65536 for 0..1e +6 }, } __END__ Rate packing modulo packing 1.67/s -- -71% modulo 5.79/s 247% --
Here, I modified your code so that $sum stores checksum in human readable form. Do you really need your subroutine to return result in machine representation? Looks strange to me. Especially since you initialize accumulator with 0, not "\x{00}\x{00}".
In reply to Re: Accessing individual bytes of a binary file as numerical values
by vr
in thread Accessing individual bytes of a binary file as numerical values
by Chris01234
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |