String-CRC

 view release on metacpan or  search on metacpan

CRC.xs  view on Meta::CPAN

 */

crc_hash_t
crc_calculate(char *p, int len)
{
    crc_hash_t hv = { HINIT1, HINIT2 };
    char *e = p + len;

    if (crc_HashLimit <= 32) {
	int s = crc_HashLimit - 8;
	U32 m = (U32)-1 >> (32 - crc_HashLimit);

	hv.h1 = 0;
	hv.h2 &= m;

	while (p < e) {
	    int i = (hv.h2 >> s) & 255;
	    /* printf("i = %d %08lx\n", i, CrcXor[i].h2); */
	    hv.h2 = ((hv.h2 << 8) & m) ^ *p ^ CrcXor[i].h2;
	    ++p;
	}
    } else if (crc_HashLimit < 32+8) {
	int s2 = 32 + 8 - crc_HashLimit;	/* bits in byte from h2 */
	U32 m = (U32)-1 >> (64 - crc_HashLimit);

	hv.h1 &= m;
	while (p < e) {
	    int i = ((hv.h1 << s2) | (hv.h2 >> (32 - s2))) & 255;
	    hv.h1 = (((hv.h1 << 8) ^ (int)(hv.h2 >> 24)) & m) ^ CrcXor[i].h1;
	    hv.h2 = (hv.h2 << 8) ^ *p ^ CrcXor[i].h2;
	    ++p;
	}
    } else {
	int s = crc_HashLimit - 40;
	U32 m = (U32)-1 >> (64 - crc_HashLimit);

	hv.h1 &= m;
	while (p < e) {
	    int i = (hv.h1 >> s) & 255;
	    hv.h1 = ((hv.h1 << 8) & m) ^ (int)(hv.h2 >> 24) ^ CrcXor[i].h1;
	    hv.h2 = (hv.h2 << 8) ^ *p ^ CrcXor[i].h2;
	    ++p;
	}
    }
    /* printf("%08lx.%08lx\n", (long)hv.h1, (long)hv.h2); */
    return(hv);
}


MODULE = String::CRC		PACKAGE = String::CRC

VERSIONCHECK: DISABLE

void
crc(data,bits=32)
    PREINIT:
	int data_len;
    INPUT:
	char *data = (char *)SvPV(ST(0),data_len);
	int bits;
    PPCODE:
	{
		crc_hash_t	h;
		U32		*rv;
		SV		*sv;

		if (bits < 16  || bits > 64) {
		    croak("String::CRC bits must be >= 16 and <= 64");
		}
		if (bits != crc_HashLimit) {
		    crc_HashLimit = bits;
		    crc_init();
		}
		h = crc_calculate(data, data_len);
		if (bits > 32 && GIMME == G_ARRAY) {
		    EXTEND(sp, 2);
		    sv = newSV(0);
		    sv_setuv(sv, (UV)h.h1);
		    PUSHs(sv_2mortal(sv));
		    sv = newSV(0);
		    sv_setuv(sv, (UV)h.h2);
		    PUSHs(sv_2mortal(sv));
		} else if (bits > 32) {
		    /* 
		     * problem.  how to return 64 bits in 32? 
		     * answer: as a string.
		     * U32 better be == 4 bytes!
		     */
		    EXTEND(sp, 1);
		    PUSHs(sv_2mortal(newSVpv((char *)&h, 8)));
		    if (sizeof(U32) != 4) croak("U32 not four bytes!");
		} else {
		    EXTEND(sp, 1);
		    sv = newSV(0);
		    sv_setuv(sv, (UV)h.h2);
		    PUSHs(sv_2mortal(sv));
		    /* PUSHs(sv_2mortal(newSViv(h.h2)));*/
		}
	}




( run in 1.499 second using v1.01-cache-2.11-cpan-5511b514fd6 )