|
Packit |
cf0d07 |
#define PERL_NO_GET_CONTEXT
|
|
Packit |
cf0d07 |
#include "EXTERN.h"
|
|
Packit |
cf0d07 |
#include "perl.h"
|
|
Packit |
cf0d07 |
#include "XSUB.h"
|
|
Packit |
cf0d07 |
|
|
Packit |
cf0d07 |
#ifndef NVTYPE
|
|
Packit |
cf0d07 |
# if defined(USE_LONG_DOUBLE) && defined(HAS_LONG_DOUBLE)
|
|
Packit |
cf0d07 |
# define NVTYPE long double
|
|
Packit |
cf0d07 |
# else
|
|
Packit |
cf0d07 |
# define NVTYPE double
|
|
Packit |
cf0d07 |
# endif
|
|
Packit |
cf0d07 |
typedef NVTYPE NV;
|
|
Packit |
cf0d07 |
#endif
|
|
Packit |
cf0d07 |
|
|
Packit |
cf0d07 |
#ifndef newSVuv
|
|
Packit |
cf0d07 |
# define newSVuv(uv) (uv > ((~((UV)0))>>1) ? newSVnv((NV)uv) : newSViv((IV)uv))
|
|
Packit |
cf0d07 |
#endif
|
|
Packit |
cf0d07 |
|
|
Packit |
cf0d07 |
#ifndef aTHX_
|
|
Packit |
cf0d07 |
# define aTHX_
|
|
Packit |
cf0d07 |
#endif
|
|
Packit |
cf0d07 |
|
|
Packit |
cf0d07 |
#ifndef SvGETMAGIC
|
|
Packit |
cf0d07 |
# define SvGETMAGIC(x) STMT_START { if (SvGMAGICAL(x)) mg_get(x); } STMT_END
|
|
Packit |
cf0d07 |
#endif
|
|
Packit |
cf0d07 |
|
|
Packit |
cf0d07 |
#define TABSIZE 256
|
|
Packit |
cf0d07 |
|
|
Packit |
cf0d07 |
static UV reflect(UV in, int width)
|
|
Packit |
cf0d07 |
{
|
|
Packit |
cf0d07 |
int i;
|
|
Packit |
cf0d07 |
UV out = 0;
|
|
Packit |
cf0d07 |
|
|
Packit |
cf0d07 |
for (i = width; in && i; i--, in >>= 1)
|
|
Packit |
cf0d07 |
out = (out << 1) | (in & 1);
|
|
Packit |
cf0d07 |
|
|
Packit |
cf0d07 |
return out << i;
|
|
Packit |
cf0d07 |
}
|
|
Packit |
cf0d07 |
|
|
Packit |
cf0d07 |
MODULE = Digest::CRC PACKAGE = Digest::CRC
|
|
Packit |
cf0d07 |
|
|
Packit |
cf0d07 |
PROTOTYPES: ENABLE
|
|
Packit |
cf0d07 |
|
|
Packit |
cf0d07 |
UV
|
|
Packit |
cf0d07 |
_reflect(in, width)
|
|
Packit |
cf0d07 |
UV in
|
|
Packit |
cf0d07 |
IV width
|
|
Packit |
cf0d07 |
|
|
Packit |
cf0d07 |
CODE:
|
|
Packit |
cf0d07 |
RETVAL = reflect(in, width);
|
|
Packit |
cf0d07 |
|
|
Packit |
cf0d07 |
OUTPUT:
|
|
Packit |
cf0d07 |
RETVAL
|
|
Packit |
cf0d07 |
|
|
Packit |
cf0d07 |
SV *
|
|
Packit |
cf0d07 |
_tabinit(width, poly, ref)
|
|
Packit |
cf0d07 |
IV width
|
|
Packit |
cf0d07 |
UV poly
|
|
Packit |
cf0d07 |
IV ref
|
|
Packit |
cf0d07 |
|
|
Packit |
cf0d07 |
PREINIT:
|
|
Packit |
cf0d07 |
UV *tab;
|
|
Packit |
cf0d07 |
UV mask, t, r, i;
|
|
Packit |
cf0d07 |
int j, wm8;
|
|
Packit |
cf0d07 |
|
|
Packit |
cf0d07 |
CODE:
|
|
Packit |
cf0d07 |
if (ref)
|
|
Packit |
cf0d07 |
poly = reflect(poly, width);
|
|
Packit |
cf0d07 |
|
|
Packit |
cf0d07 |
mask = ((UV)1)<<(width-1);
|
|
Packit |
cf0d07 |
mask = mask + (mask-1);
|
|
Packit |
cf0d07 |
|
|
Packit |
cf0d07 |
i = TABSIZE*sizeof(UV);
|
|
Packit |
cf0d07 |
RETVAL = newSV(i);
|
|
Packit |
cf0d07 |
SvPOK_only(RETVAL);
|
|
Packit |
cf0d07 |
SvCUR_set(RETVAL, i);
|
|
Packit |
cf0d07 |
tab = (UV *) SvPVX(RETVAL);
|
|
Packit |
cf0d07 |
|
|
Packit |
cf0d07 |
if (!ref) {
|
|
Packit |
cf0d07 |
t = ((UV)1) << (width - 1);
|
|
Packit |
cf0d07 |
wm8 = width - 8;
|
|
Packit |
cf0d07 |
}
|
|
Packit |
cf0d07 |
|
|
Packit |
cf0d07 |
for (i = 0; i < TABSIZE; i++) {
|
|
Packit |
cf0d07 |
if (ref) {
|
|
Packit |
cf0d07 |
r = i;
|
|
Packit |
cf0d07 |
for (j = 0; j < 8; j++)
|
|
Packit |
cf0d07 |
if (r & 1)
|
|
Packit |
cf0d07 |
r = (r >> 1) ^ poly;
|
|
Packit |
cf0d07 |
else
|
|
Packit |
cf0d07 |
r >>= 1;
|
|
Packit |
cf0d07 |
}
|
|
Packit |
cf0d07 |
else {
|
|
Packit |
cf0d07 |
r = i << (width - 8);
|
|
Packit |
cf0d07 |
for (j = 0; j < 8; j++)
|
|
Packit |
cf0d07 |
if (r & t)
|
|
Packit |
cf0d07 |
r = (r << 1) ^ poly;
|
|
Packit |
cf0d07 |
else
|
|
Packit |
cf0d07 |
r <<= 1;
|
|
Packit |
cf0d07 |
}
|
|
Packit |
cf0d07 |
tab[i] = r & mask;
|
|
Packit |
cf0d07 |
}
|
|
Packit |
cf0d07 |
|
|
Packit |
cf0d07 |
OUTPUT:
|
|
Packit |
cf0d07 |
RETVAL
|
|
Packit |
cf0d07 |
|
|
Packit |
cf0d07 |
SV *
|
|
Packit |
cf0d07 |
_crc(message, width, init, xorout, refin, refout, cont, table)
|
|
Packit |
cf0d07 |
SV *message
|
|
Packit |
cf0d07 |
IV width
|
|
Packit |
cf0d07 |
UV init
|
|
Packit |
cf0d07 |
UV xorout
|
|
Packit |
cf0d07 |
IV refin
|
|
Packit |
cf0d07 |
IV refout
|
|
Packit |
cf0d07 |
IV cont
|
|
Packit |
cf0d07 |
SV *table
|
|
Packit |
cf0d07 |
|
|
Packit |
cf0d07 |
PREINIT:
|
|
Packit |
cf0d07 |
UV crc, mask, *tab;
|
|
Packit |
cf0d07 |
STRLEN len;
|
|
Packit |
cf0d07 |
const char *msg, *end;
|
|
Packit |
cf0d07 |
|
|
Packit |
cf0d07 |
CODE:
|
|
Packit |
cf0d07 |
SvGETMAGIC(message);
|
|
Packit |
cf0d07 |
|
|
Packit |
cf0d07 |
msg = SvPV(message, len);
|
|
Packit |
cf0d07 |
end = msg + len;
|
|
Packit |
cf0d07 |
mask = ((UV)1)<<(width-1);
|
|
Packit |
cf0d07 |
mask = mask + (mask-1);
|
|
Packit |
cf0d07 |
tab = (UV *) SvPVX(table);
|
|
Packit |
cf0d07 |
|
|
Packit |
cf0d07 |
crc = refin ? reflect(init, width) : init;
|
|
Packit |
cf0d07 |
if (cont) {
|
|
Packit |
cf0d07 |
crc = (init ^ xorout) & mask;
|
|
Packit |
cf0d07 |
if (refout ^ refin)
|
|
Packit |
cf0d07 |
crc = reflect(crc, width);
|
|
Packit |
cf0d07 |
}
|
|
Packit |
cf0d07 |
|
|
Packit |
cf0d07 |
if (refin) {
|
|
Packit |
cf0d07 |
while (msg < end)
|
|
Packit |
cf0d07 |
crc = (crc >> 8) ^ tab[(crc ^ *msg++) & 0xFF];
|
|
Packit |
cf0d07 |
}
|
|
Packit |
cf0d07 |
else {
|
|
Packit |
cf0d07 |
int wm8 = width - 8;
|
|
Packit |
cf0d07 |
while (msg < end)
|
|
Packit |
cf0d07 |
crc = (crc << 8) ^ tab[((crc >> wm8) ^ *msg++) & 0xFF];
|
|
Packit |
cf0d07 |
}
|
|
Packit |
cf0d07 |
|
|
Packit |
cf0d07 |
if (refout ^ refin)
|
|
Packit |
cf0d07 |
crc = reflect(crc, width);
|
|
Packit |
cf0d07 |
|
|
Packit |
cf0d07 |
crc = (crc ^ xorout) & mask;
|
|
Packit |
cf0d07 |
|
|
Packit |
cf0d07 |
RETVAL = newSVuv(crc);
|
|
Packit |
cf0d07 |
|
|
Packit |
cf0d07 |
OUTPUT:
|
|
Packit |
cf0d07 |
RETVAL
|
|
Packit |
cf0d07 |
|
|
Packit |
cf0d07 |
SV *
|
|
Packit |
cf0d07 |
_crc64(message, crc=0)
|
|
Packit |
cf0d07 |
SV * message
|
|
Packit |
cf0d07 |
UV crc
|
|
Packit |
cf0d07 |
|
|
Packit |
cf0d07 |
PREINIT:
|
|
Packit |
cf0d07 |
unsigned long long poly64rev = 0xd800000000000000ULL;
|
|
Packit |
cf0d07 |
unsigned long long part;
|
|
Packit |
cf0d07 |
int i, j;
|
|
Packit |
cf0d07 |
static int init = 0;
|
|
Packit |
cf0d07 |
static unsigned long long CRCTable[256];
|
|
Packit |
cf0d07 |
STRLEN len;
|
|
Packit |
cf0d07 |
const char *msg, *end;
|
|
Packit |
cf0d07 |
|
|
Packit |
cf0d07 |
CODE:
|
|
Packit |
cf0d07 |
SvGETMAGIC(message);
|
|
Packit |
cf0d07 |
msg = SvPV(message, len);
|
|
Packit |
cf0d07 |
end = msg + len;
|
|
Packit |
cf0d07 |
|
|
Packit |
cf0d07 |
if (!init) {
|
|
Packit |
cf0d07 |
init = 1;
|
|
Packit |
cf0d07 |
|
|
Packit |
cf0d07 |
for (i = 0; i < 256; i++) {
|
|
Packit |
cf0d07 |
part = i;
|
|
Packit |
cf0d07 |
for (j = 0; j < 8; j++) {
|
|
Packit |
cf0d07 |
if (part & 1)
|
|
Packit |
cf0d07 |
part = (part >> 1) ^ poly64rev;
|
|
Packit |
cf0d07 |
else
|
|
Packit |
cf0d07 |
part >>= 1;
|
|
Packit |
cf0d07 |
}
|
|
Packit |
cf0d07 |
CRCTable[i] = part;
|
|
Packit |
cf0d07 |
}
|
|
Packit |
cf0d07 |
}
|
|
Packit |
cf0d07 |
while (msg < end)
|
|
Packit |
cf0d07 |
crc = CRCTable[(crc ^ *msg++) & 0xff] ^ (crc >> 8);
|
|
Packit |
cf0d07 |
|
|
Packit |
cf0d07 |
RETVAL = newSVuv(crc);
|
|
Packit |
cf0d07 |
|
|
Packit |
cf0d07 |
OUTPUT:
|
|
Packit |
cf0d07 |
RETVAL
|
|
Packit |
cf0d07 |
|