I'm new to perl and i would like to know why the arguments are not correcly passed to the subroutine. Also, are the output values correct?
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 );
Thanks!
An use ...
statement is always executed at compile time, and is not subject to normal control flow. During compile time, the @_
array does not contain elements, so $_[1]
will be undefined. You should be using regular variables:
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;
}
Oh, and you should be specifying the $poly
as an integer, not a string: $poly = 0x8005
, without the quotes.
As I pointed out in a comment on a similar question of yours, there already is a Perl module that implements CRC algorithms: Digest::CRC
. The important parts are coded in C for performance. The provided functions are highly parameterizable. I urge you to find a way to use that module instead of reinventing the wheel.