#include static unsigned long crctable[256]; void calc_crc_table(void) { unsigned long poly = 0xedb88320, value, idx, i; for (idx = 0 ; idx < 256 ; idx++) { for (value = idx, i = 0 ; i < 8 ; i++) { if (value & 1) { value >>= 1; value ^= poly; } else { value >>= 1; } } crctable[idx] = value; } } unsigned long calc_crc(unsigned char *buf, unsigned long buflen) { unsigned long crc = 0xffffffff; while (buflen--) crc = (crc >> 8) ^ crctable[*buf++ ^ crc & 0xff]; return ~crc; } unsigned char mkhex(char c) { char oc = c; if (c < '0') goto err; c -= '0'; if (c <= 9) return c; if (c < 'A'-'0') goto err; c -= 'A'-'0'; if (c <= 6) return 10+c; if (c < 'a'-'A') goto err; c -= 'a' - 'A'; if (c <= 6) return 10+c; err: fprintf(stderr, "invalid character %c (%hhx)\n", oc, oc); exit(1); } unsigned long interpol(char *src, char *dst, const unsigned long dstlen) { unsigned long i=0; register char c; while (*src && i < dstlen) { if ((c = *src++) == '\\') if ((c = *src++) == 'x') { c = mkhex(*src++) << 4; c |= mkhex(*src++); } else if (!c) break; dst[i++] = c; } return i; } int main(int argc, char **argv) { int i; char buf[256]; unsigned long buflen = 256; calc_crc_table(); if (argc > 1) { buflen = interpol(argv[1], buf, buflen); printf("%d crc: %.8X\n", buflen, calc_crc((unsigned char *)buf, buflen)); } else for (i=0 ; i<256 ; i+=16) printf("%.8X %.8X %.8X %.8X %.8X %.8X %.8X %.8X %.8X %.8X %.8X %.8X %.8X %.8X %.8X %.8X\n", crctable[i], crctable[i+1], crctable[i+2], crctable[i+3], crctable[i+4], crctable[i+5], crctable[i+6], crctable[i+7], crctable[i+8], crctable[i+9], crctable[i+10], crctable[i+11], crctable[i+12], crctable[i+13], crctable[i+14], crctable[i+15]); return 0; }