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

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.

Replies are listed 'Best First'.
Re^4: CRC of a string
by Dirk80 (Pilgrim) on Nov 19, 2009 at 10:16 UTC

    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.

        Hi,

        Thank you very much for your answer. Now I read the whole tutorial perlpacktut. And I did many experiments with pack/unpack. And now I know the behaviour of "N". If you use "N" with unpack and in memory is less than 4 bytes then nothing is unpacked. "N" with unpack is only unpacking something if there are at least 4 bytes in memory left. So you were totally right. Adding "\0\0\0" to the string will always work.

        Because the pack tutorial was so interesting I still did not read the perlsub tutorial. But this will come next. Because you are right. At the moment I don't know the difference between calling a function with & or without, ...

        Greetings,

        Dirk