in reply to Re: CRC of a string
in thread CRC of a string

Interesting! Your code works for me, with the same result, but when I try
perldoc -f pack | grep %

I get only 3 lines - the same three as found searching for '%' in pack - none of which mention the use of '%' in the (un)pack template.

Replies are listed 'Best First'.
Re^3: CRC of a string
by AnomalousMonk (Archbishop) on Nov 18, 2009 at 21:49 UTC
    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.

      Thank you very much for your great answers. So I could learn a lot.

      Here the final solution:

      #!/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); }
        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.