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;