in reply to Conversion of C code to Perl-ese.

This should be it (no guarantees, you might want to verify):
sub checksum ($) { my $string = shift; my @chars = split //, $string; my $sum; $sum += $_ & 0x7F for (@chars[0..@chars-5]); # add ASCII values up $sum += hex(join('', @chars[@chars-4..@chars-1])); # add the last four characters interpreted as hex number return (($sum & 0xFFFF == 0) ? 0 : 1); }

Cheers, CombatSquirrel

Replies are listed 'Best First'.
Re: Re: Conversion of C code to Perl-ese.
by gooch (Monk) on Aug 13, 2003 at 23:50 UTC
    Hmmm, looks like I was on the right track all along, as I can follow your Perl pretty well...

    Unfortunately that calls into question if the C code was ever doing what it purported to do in the first place, as the routine should fail if, for example the inbound string is <SOH>9998FF1B<ETX> - and although as far as I can tell you have provided an exact duplicate of what the C code does, I ran the above string, through the provided subroutine, and received "0"...
    So...
    According to the description, the C code purports to do the following:
    "The Checksum is a series of four ASCII-hexidecimal characters which provide a check on the integrity of all characters preceeding it. The four characters represent a 16-bit binary count which is the 2's complimented sum of the 8-bit binary representations of the message characters. The data integrity check is done by converting the four checksum characters into a 16-bit binary, and adding the 8-bit binary representation of the message characters to it. The binary result should be zero."
    Implied, is that any value other than zero indicates a checksum failure.

    Can anyone tell me if the C code is actually doing that, or for that matter how CombatSquirrel's kindly provided code sample could be made to perform this (to me rather arcane) act?

    Still out of my depth here, but at least someone threw me a floatation device.

    Thanks CombatSquirrel.
    Mike Gucciard
      Yes, I believe that the C code is doing what your documentation describes. However, your assumption about return values may be incorrect. Looking at the C code, I believe the function returns 0 if the checksum succeeds (is correct) and 1 if the checksum fails (is incorrect).

      See if that matches your sample results.

      Not documented in the C code is what happens if bufflen is less than 5 or greater than the actual size of the buff. You may have trouble getting Perl to replicate the behavior in these cases (accessing random memory on the stack).

      -- Eric Hammond