Right you are. My memory failed me. It is discussed in unpack and seems to be referred to as a 'template field prefix'. Search for '%' or 'prefix'. Reply fixed. | [reply] |
#!/usr/bin/perl
use strict;
use warnings;
my $str = "/etc/test2.sh"; # checksum32: 990644297
my $checksum32 = &calcChecksum32($str);
print $checksum32 . "\n";
sub calcChecksum32()
{
my $str = $_[0];
my $nb_pad_bytes = 4 - (length($str) % 4);
$str .= "\0" x $nb_pad_bytes;
unpack('%32N*', $str);
}
| [reply] [d/l] |
Note that the calculation 4 - (length($str) % 4) will cause four null bytes to be appended to a string that is an exactly even number of 'N' fields long. As this effectively adds a zero to an arithmetic checksum, there should be no effect. However, there may be other, similar situations in which there is a significant effect! The current unpack-ing behavior of the N* field specifier and others of its ilk is to ignore any bytes at the end of a string that do not constitute a complete field. If this is true, it is sufficient to simply append a constant string of three null bytes (in the case of the N specifier) to the end of every string. Unfortunately, this behavior does not seem not be explicitly specified in the current documentation.
Also note that you define the calcChecksum32 function with a () prototype for an empty argument list, then invoke the function (with an argument!) with the & sigil, which causes any prototype to be ignored. A good rule is to avoid prototypes unless you understand exactly how they work; most programmers, especially those from a C/C++ background, simply don't.
It is also good practice to avoid using the & sigil when invoking functions, using, e.g., calcChecksum32($string) instead. Among other things, this will allow prototypes, if you ever do use them, to actually have some effect! See perlsub for info on prototypes, subroutine invocation, etc.
| [reply] [d/l] [select] |