(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

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.