2

我是 perl 的新手,我想知道为什么参数没有正确传递给子例程。另外,输出值是否正确?

use strict;

sub crc16 {
     use constant POLY => $_[1];
     my $crc = 0;
     for my $c ( unpack 'C*', $_[0] ) {
         $crc ^= $c;
         for my $b ( 0 .. 7 ) {
             my $carry = $crc & 1;
             $crc >>= 1;
             if( $carry ) {
                 $crc ^= POLY;
             }
         }
     }
     return $crc;
}

my $data = "1234";
my $poly = "0x8005";

printf "crc: %04x\n", crc16( $data, $poly );

谢谢!

4

1 回答 1

2

use ...语句总是在编译时执行,不受正常控制流的约束。在编译期间,@_数组不包含元素,因此$_[1]将是未定义的。您应该使用常规变量:

sub crc16 {
   my ($string, $poly) = @_;
   my $crc = 0;
   for my $c ( unpack 'C*', $string ) {
      $crc ^= $c;
      for ( 0 .. 7 ) {
         my $carry = $crc & 1;
         $crc >>= 1;
         $crc ^= $poly if $carry;
      }
   }
   return $crc;
}

哦,您应该将 指定$poly为整数,而不是字符串: $poly = 0x8005,不带引号。


正如我在对您的类似问题的评论中指出的那样,已经有一个实现 CRC 算法的 Perl 模块:Digest::CRC. 为了性能,重要的部分用 C 编码。提供的函数是高度可参数化的。我敦促您找到一种使用该模块的方法,而不是重新发明轮子。

于 2013-06-15T16:59:17.083 回答