Just noticed this...
In both the original, and my version, there seems to be some wasted logic. See comments that start with ## below.
if (length($payload)%2) {
my $padded = substr $payload, 0, -1;
$padded .= "\0";
$padded .= substr $payload, -1;
## above: ok, so the next to the last byte
## is guaranteed to be null since we just
## explicitly set it
if (ord(substr $padded, -1) >= 128) {
my $end = ord(substr $padded, -2, 1);
##
## above: now we're grabbing the next to the last
## byte, even though we already know it's a null?
##
my $endend = ord(substr $padded, -1);
$end--;
## now we decrement it, knowing full well it's
## going to be -1?
$endend--;
###DEBUG:
printf "CMPSAT = %i %i\n", $end, $endend;
# if 0 before --, then -1 results in warning to pack below
# -1 is in essense \xff or 255
if ($end == -1) { $end = 255 }
##
## above,of course, it's going to == -1, and thus
## at this point, always reset to 255
##
if ($endend == -1) { $endend = 255 }
$padded = substr $padded, 0, -2;
$padded .= CORE::pack('CC', $end, $endend);
}
$payload = $padded;
}
It would seem then, that you could simplify all of that out, and just decrement the last byte by one?
sub prepchksum {
my ($payload) = @_;
printf "BEFORE = %s\n", (CORE::unpack "H*", $payload);
if (length($payload)%2) {
$payload =~ s#(.)$#\0$1#;
printf "MID1 = %s\n", (CORE::unpack "H*", $payload);
# Compensate off-by-one error
if (ord(substr $payload, -1) >= 128) {
$payload=~s#(.)$#pack('C',(ord($2)-1)&255)#e;
}
}
printf "AFTER = %s\n", (CORE::unpack "H*", $payload);
}
Or perhaps there's a bug somewhere, either in the 'C' implementation you based this on, or your original port? |