Subject: | Add CRC-64 support |
The attached patch contains a very simple patch to add XS CRC-64-
implementation in Bio::SeqIO::swiss (from the Bioperl distribution).
The correct solution, rather than the attached patch, is probably to
figure out the right values and add crc64 to the _typedef hash but I
was unable to "guess" them.
This patch only adds the crc64 function and its XS implementation
_crc64. It doesn't work with the OO interface and it doesn't work
without XS, but for what it's worth, it works.
The C source has been adapted from
http://bioinf.cs.ucl.ac.uk/downloads/crc64/crc64.c
Subject: | 0001-add-crc64-support.patch |
From 11fda8362ebcacef789f20361808c75411aee8bb Mon Sep 17 00:00:00 2001
From: Anders Ossowicki <aowi@novozymes.com>
Date: Wed, 23 Sep 2009 15:03:31 +0200
Subject: [PATCH] add crc64 support
This is an ultra-simple XS implementatation based on
http://bioinf.cs.ucl.ac.uk/downloads/crc64/crc64.c which is modified from
swissprot[1]. It only works through the fucntional interface, not the
object-oriented one.
[1] ftp://ftp.ebi.ac.uk/pub/software/swissprot/Swissknife/old/SPcrc.tar.gz
---
CRC.xs | 41 +++++++++++++++++++++++++++++++++++++++++
lib/Digest/CRC.pm | 17 ++++++++++++++---
t/crc.t | 3 ++-
3 files changed, 57 insertions(+), 4 deletions(-)
diff --git a/CRC.xs b/CRC.xs
index 8de05b0..d44c1f0 100644
--- a/CRC.xs
+++ b/CRC.xs
@@ -148,3 +148,44 @@ _crc(message, width, init, xorout, refin, refout, table)
OUTPUT:
RETVAL
+
+SV *
+_crc64(message)
+ SV * message
+
+ PREINIT:
+ unsigned long long poly64rev = 0xd800000000000000;
+ unsigned long long crc = 0x0000000000000000;
+ unsigned long long part;
+ int i, j;
+ static int init = 0;
+ static unsigned long long CRCTable[256];
+ STRLEN len;
+ const char *msg, *end;
+
+ CODE:
+ SvGETMAGIC(message);
+ msg = SvPV(message, len);
+ end = msg + len;
+
+ if (!init) {
+ init = 1;
+
+ for (i = 0; i < 256; i++) {
+ part = i;
+ for (j = 0; j < 8; j++) {
+ if (part & 1)
+ part = (part >> 1) ^ poly64rev;
+ else
+ part >>= 1;
+ }
+ CRCTable[i] = part;
+ }
+ }
+ while (msg < end)
+ crc = CRCTable[(crc ^ *msg++) & 0xff] ^ (crc >> 8);
+
+ RETVAL = newSVuv(crc);
+
+ OUTPUT:
+ RETVAL
diff --git a/lib/Digest/CRC.pm b/lib/Digest/CRC.pm
index 3a6b615..938e3d8 100644
--- a/lib/Digest/CRC.pm
+++ b/lib/Digest/CRC.pm
@@ -8,12 +8,13 @@ require Exporter;
@ISA = qw(Exporter);
@EXPORT_OK = qw(
- crc8 crcccitt crc16 crc32 crc
+ crc8 crcccitt crc16 crc32 crc64 crc
crc_hex crc_base64
crcccitt_hex crcccitt_base64
crc8_hex crc8_base64
crc16_hex crc16_base64
crc32_hex crc32_base64
+ crc64_hex crc64_base64
);
$VERSION = '0.14';
@@ -267,6 +268,11 @@ sub crc16 { crc($_[0],@{$_typedef{crc16}}) }
sub crc32 { crc($_[0],@{$_typedef{crc32}}) }
+# CRC64
+# special XS implementation (_crc64)
+
+sub crc64 { _crc64($_[0]) }
+
sub crc_hex { _encode_hex &crc }
sub crc_base64 { _encode_base64 &crc }
@@ -287,6 +293,10 @@ sub crc32_hex { _encode_hex &crc32 }
sub crc32_base64 { _encode_base64 &crc32 }
+sub crc64_hex { _encode_hex &crc64 }
+
+sub crc64_base64 { _encode_base64 &crc64 }
+
1;
__END__
@@ -298,7 +308,8 @@ Digest::CRC - Generic CRC functions
# Functional style
- use Digest::CRC qw(crc32 crc16 crcccitt crc crc8);
+ use Digest::CRC qw(crc64 crc32 crc16 crcccitt crc crc8);
+ $crc = crc64("123456789");
$crc = crc32("123456789");
$crc = crc16("123456789");
$crc = crcccitt("123456789");
@@ -325,7 +336,7 @@ Digest::CRC - Generic CRC functions
The B<Digest::CRC> module calculates CRC sums of all sorts.
It contains wrapper functions with the correct parameters for CRC-CCITT,
-CRC-16 and CRC-32.
+CRC-16, CRC-32 and CRC-64.
=head1 AUTHOR
diff --git a/t/crc.t b/t/crc.t
index 4f5286e..54978e9 100644
--- a/t/crc.t
+++ b/t/crc.t
@@ -22,8 +22,9 @@ use Digest::CRC qw(crc32 crc16 crcccitt crc8);
ok(1, 'use');
my $input = "123456789";
-my ($crc32,$crc16,$crcccitt,$crc8) = (crc32($input),crc16($input),crcccitt($input),crc8($input));
+my ($crc64,$crc32,$crc16,$crcccitt,$crc8) = (crc64($input),crc32($input),crc16($input),crcccitt($input),crc8($input));
+ok($crc64 == 5121746406857240574, 'crc64');
ok($crc32 == 3421780262, 'crc32');
$crc32=$crc32^0xffffffff;
ok(crc32($input.join('',
--
1.6.0.4