This queue is for tickets about the Digest-CRC CPAN distribution.

Report information
The Basics
Id:
70535
Status:
resolved
Priority:
Low/Low
Queue:

People
Owner:
OLIMAUL [...] cpan.org
Requestors:
pebolle [...] tiscali.nl
Cc:
AdminCc:

BugTracker
Severity:
Wishlist
Broken in:
0.16
Fixed in:
(no value)



Subject: Add 'cont' support to Functional style
0) Running Digest-CRC-0.16, using perl v5.14.1 on linux v3.1-rc3. (Identical issue with Digest-CRC-0.14, using perl v5.12.3 on linux v3.0.3.) 1) crc.pl is a (silly) test that uses several methods to compute identical CRC32 checksums. It includes a "two step" run of crc() (ie, the functional style), which currently fails because the Functional style does not support "cont". (The test supplies crc() with an 8th argument that it will silently ignore.) Output currently is: crc32: 0x51f9be31 crc32: 0xaca043fa crc32: 0x51f9be31 crc32: 0x51f9be31 crc32: 0x51f9be31 2) cont.patch adds "cont" support to the Functional style. (It also tries to make the sequence of arguments to crc() and new() consistent in the code and documentation, which is mostly nitpicking.) Review would be appreciated. Boring output using this patch: crc32: 0x51f9be31 crc32: 0x51f9be31 crc32: 0x51f9be31 crc32: 0x51f9be31 crc32: 0x51f9be31 3) The non-xs code is (apparently) untested. (4) If (something like) this patch is acceptable, a follow up could be to add support for crc32( $additional_input, $current_digest ); and similar.)
Subject: cont.patch
diff -up Digest-CRC-0.16/CRC.xs.cont Digest-CRC-0.16/CRC.xs --- Digest-CRC-0.16/CRC.xs.cont 2010-09-20 08:45:11.000000000 +0200 +++ Digest-CRC-0.16/CRC.xs 2011-08-27 00:01:53.868110812 +0200 @@ -105,13 +105,14 @@ _tabinit(width, poly, ref) RETVAL SV * -_crc(message, width, init, xorout, refin, refout, table) +_crc(message, width, init, xorout, refin, refout, cont, table) SV *message IV width UV init UV xorout IV refin IV refout + IV cont SV *table PREINIT: @@ -122,6 +123,11 @@ _crc(message, width, init, xorout, refin CODE: SvGETMAGIC(message); + if (cont) { + init = (init ^ xorout); + if (refin) + init = reflect(init, width); + } crc = refin ? reflect(init, width) : init; msg = SvPV(message, len); end = msg + len; diff -up Digest-CRC-0.16/lib/Digest/CRC.pm.cont Digest-CRC-0.16/lib/Digest/CRC.pm --- Digest-CRC-0.16/lib/Digest/CRC.pm.cont 2010-09-29 12:04:59.000000000 +0200 +++ Digest-CRC-0.16/lib/Digest/CRC.pm 2011-08-27 00:01:53.875111946 +0200 @@ -83,8 +83,12 @@ sub _tabinit($$$) { \@crctab; } -sub _crc($$$$$$$) { - my ($message,$width,$init,$xorout,$refin,$refout,$tab) = @_; +sub _crc($$$$$$$$) { + my ($message,$width,$init,$xorout,$refin,$refout,$cont,$tab) = @_; + if ($cont) { + $init = ($init ^ $xorout); + $init = _reflect($init, $width) if $refin; + } my $crc = $init; if ($refin == 1) { $crc = _reflect($crc,$width); @@ -118,11 +122,11 @@ sub _crc($$$$$$$) { ENOXS %_typedef = ( -# name, [width,init,xorout,refout,poly,refin); - crc8 => [8,0,0,0,0x07,0], - crcccitt => [16,0xffff,0,0,0x1021,0], - crc16 => [16,0,0,1,0x8005,1], - crc32 => [32,0xffffffff,0xffffffff,1,0x04C11DB7,1], +# name, [width,init,xorout,refout,poly,refin,cont); + crc8 => [8,0,0,0,0x07,0,0], + crcccitt => [16,0xffff,0,0,0x1021,0,0], + crc16 => [16,0,0,1,0x8005,1,0], + crc32 => [32,0xffffffff,0xffffffff,1,0x04C11DB7,1,0], ); sub new { @@ -130,11 +134,11 @@ sub new { my %params=@_; my $class = ref($that) || $that; my $self = {map { ($_ => $params{$_}) } - qw(type width init xorout poly refin refout cont)}; + qw(type width init xorout refout poly refin cont)}; bless $self, $class; $self->reset(); map { if (defined($params{$_})) { $self->{$_} = $params{$_} } } - qw(type width init xorout poly refin refout cont); + qw(type width init xorout refout poly refin cont); $self } @@ -153,6 +157,7 @@ sub reset { $self->{refout} = $typeparams->[3], $self->{poly} = $typeparams->[4], $self->{refin} = $typeparams->[5], + $self->{cont} = $typeparams->[6], } $self->{_tab} = _tabinit($self->{width}, $self->{poly}, $self->{refin}); $self->{_data} = undef; @@ -212,12 +217,8 @@ sub digest { my $crc; if (!$self->{_crc}) { my $init = $self->{init}; - if ($self->{cont}) { - $init = ($self->{init} ^ $self->{xorout}); - $init = _reflect($init, $self->{width}) if $self->{refin}; - } $crc =_crc($self->{_data},$self->{width},$init,$self->{xorout}, - $self->{refin},$self->{refout},$self->{_tab}); + $self->{refin},$self->{refout},$self->{cont},$self->{_tab}); } else { $crc = $self->{_crc}; $self->{_crc} = undef; @@ -253,8 +254,8 @@ sub clone { # Procedural interface: sub crc { - my ($message,$width,$init,$xorout,$refout,$poly,$refin) = @_; - _crc($message,$width,$init,$xorout,$refin,$refout,_tabinit($width,$poly,$refin)); + my ($message,$width,$init,$xorout,$refout,$poly,$refin,$cont) = @_; + _crc($message,$width,$init,$xorout,$refin,$refout,$cont,_tabinit($width,$poly,$refin)); } # CRC8 @@ -326,14 +327,14 @@ Digest::CRC - Generic CRC functions $crc = crcccitt("123456789"); $crc = crc8("123456789"); - $crc = crc($input,$width,$init,$xorout,$refout,$poly,$refin); + $crc = crc($input,$width,$init,$xorout,$refout,$poly,$refin,$cont); # OO style use Digest::CRC; $ctx = Digest::CRC->new(type=>"crc16"); $ctx = Digest::CRC->new(width=>16, init=>0x2345, xorout=>0x0000, - poly=>0x8005, refin=>1, refout=>1, cont=>1); + refout=>1, poly=>0x8005, refin=>1, cont=>1); $ctx->add($data); $ctx->addfile(*FILE); diff -up Digest-CRC-0.16/t/crc.t.cont Digest-CRC-0.16/t/crc.t --- Digest-CRC-0.16/t/crc.t.cont 2010-09-29 13:35:54.000000000 +0200 +++ Digest-CRC-0.16/t/crc.t 2011-08-27 00:04:07.772787489 +0200 @@ -73,8 +73,8 @@ $ctx = Digest::CRC->new(type=>"crc16"); $ctx->add($input); ok($ctx->digest == 47933, 'OO crc16'); -$ctx = Digest::CRC->new(width=>16,init=>0,xorout=>0,poly=>0x3456, - refin=>1,refout=>1); +$ctx = Digest::CRC->new(width=>16,init=>0,xorout=>0,refout=>1,poly=>0x3456, + refin=>1,cont=>0); $ctx->add($input); ok($ctx->digest == 12803, 'OO crc16 poly 3456'); @@ -83,13 +83,13 @@ $ctx->add($input); ok($ctx->digest == 244, 'OO crc8'); # crc8 test from Mathis Moder <mathis@pixelconcepts.de> -$ctx = Digest::CRC->new(width=>8, init=>0xab, xorout=>0x00,poly=>0x07, - refin=>0, refout=>0); +$ctx = Digest::CRC->new(width=>8, init=>0xab, xorout=>0x00, refout=>0, poly=>0x07, + refin=>0, cont=>0); $ctx->add($input); ok($ctx->digest == 135, 'OO crc8 init=ab'); -$ctx = Digest::CRC->new(width=>8, init=>0xab, xorout=>0xff,poly=>0x07, - refin=>1, refout=>1); +$ctx = Digest::CRC->new(width=>8, init=>0xab, xorout=>0xff, refout=>1, poly=>0x07, + refin=>1, cont=>0); $ctx->add("f1"); ok($ctx->digest == 106, 'OO crc8 init=ab, refout');
Subject: crc.pl
#! /usr/bin/env perl use 5.010; use strict; use warnings; use Digest::CRC qw( crc ); my $in0 = "TEST "; my $in1 = "STRING"; my $out; $out = crc( $in0 . $in1, 32, 0xffffffff, 0xffffffff, 1, 0x04C11DB7, 1, 0 ); printf "crc32: 0x%08x\n", $out; $out = crc( $in0, 32, 0xffffffff, 0xffffffff, 1, 0x04C11DB7, 1, 0 ); $out = crc( $in1, 32, $out, 0xffffffff, 1, 0x04C11DB7, 1, 1 ); printf "crc32: 0x%08x\n", $out; my $ctx = Digest::CRC->new( width=>32, init=>0xffffffff, xorout=>0xffffffff, refout=>1, poly=>0x04C11DB7, refin=>1, cont=>0 ); $ctx->add( $in0 . $in1 ); printf "crc32: 0x%08x\n", $ctx->digest; $ctx = Digest::CRC->new( width=>32, init=>0xffffffff, xorout=>0xffffffff, refout=>1, poly=>0x04C11DB7, refin=>1, cont=>0 ); $ctx->add( $in0 ); $ctx->add( $in1 ); printf "crc32: 0x%08x\n", $ctx->digest; $ctx = Digest::CRC->new( width=>32, init=>0xffffffff, xorout=>0xffffffff, refout=>1, poly=>0x04C11DB7, refin=>1, cont=>0 ); $ctx->add( $in0 ); $ctx = Digest::CRC->new( width=>32, init=>$ctx->digest, xorout=>0xffffffff, refout=>1, poly=>0x04C11DB7, refin=>1, cont=>1 ); $ctx->add( $in1 ); printf "crc32: 0x%08x\n", $ctx->digest;
Hi, thanks for the patch. It is part of version 0.17 which should be available tomorrow. Oliver


This service runs on Request Tracker, is sponsored by The Perl Foundation, and maintained by Best Practical Solutions.

Please report any issues with rt.cpan.org to rt-cpan-admin@bestpractical.com.