Wait. You mean they magically become integers when they need to. Right? Because, what I've noticed here is that they magically become -1 when Perl runs out of tricks! That is when I put a # in front of the "use integer;" line. Please look at my code below:
use strict;
use warnings;
use integer;
my $string = 'Hello World!';
my $x = Checksum($string);
printf("\n\nChecksum = %0.8X\n", $x);
exit;
#
# This function returns a 32-bit integer.
#
# Usage: LONG = Checksum(STRING)
#
sub Checksum
{
my $C = 0x55555555; # Starting value.
# Make sure we got a valid string argument.
@_ or return $C;
my $S = shift;
defined $S or return $C;
# Start the loop with the
# last character of the string:
my $i = length($S);
my $V;
my $H;
my $L;
while ($i--)
{
# $V contains the character code shifted
# to the left by either 0, 8, 16, or 24 bits:
$V = ((vec($S, $i, 8) + 1) << (($i & 3) << 3));
# We add this value to the checksum $C
$C += $V;
# Then we rotate this 32-bit "checksum" to
# the left by 1. There is no ROL operator
# in Perl, so we take the 32nd bit ($H) and
# then we shift the rest to the left, and
# finally we OR the low and high bits
# together to achieve the desired rotation.
# So, it would look something like this:
# 01110101011111111101000001110000 <<<
# 11101010111111111010000011100000 <<<
# 11010101111111110100000111000001 <<<
# 10101011111111101000001110000011 <<<
# 01010111111111010000011100000111 <<<
# 10101111111110100000111000001110 <<<
# 01011111111101000001110000011101 <<<
# 10111111111010000011100000111010 <<<
# 01111111110100000111000001110101 <<<
$H = (($C >> 31) & 1);
$L = (($C << 1) & 0xFFFFFFFE);
$C = $H | $L;
# Now, here we print a snapshot of $V
# and we print the high bit and the low
# portion of the integer:
printf("\nV=%0.8X \tH=$H L=%0.32b", $V, $L);
}
# Make sure we return a 32-bit integer
return $C & 0xFFFFFFFF;
}
|