Merge remote-tracking branch 'tiny_crc32/master'

This commit is contained in:
Connor Olding 2018-10-11 16:45:38 +02:00
commit 93f7ce654d

60
crc32.c Normal file
View file

@ -0,0 +1,60 @@
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#ifndef BUFFER
#define BUFFER 4096
#endif
uint8_t msg[BUFFER];
/* CRC-32, eg. ethernet */
const uint32_t crc32_tbl[] = {
0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
};
/* the idea is to act on nybbles instead of bytes to require less CPU cache */
uint32_t crc32_calc(uint8_t *ptr, int cnt, uint32_t crc)
{
while (cnt--) {
crc = (crc >> 4) ^ crc32_tbl[(crc & 0xf) ^ (*ptr & 0xf)];
crc = (crc >> 4) ^ crc32_tbl[(crc & 0xf) ^ (*(ptr++) >> 4)];
}
return crc;
}
int main(int argc, char **argv)
{
int len;
uint32_t v32 = ~0;
FILE *f;
if (argc == 1) {
freopen(NULL, "rb", stdin);
f = stdin;
} else if (argc == 2) {
f = fopen(argv[1], "rb");
if (f == NULL) {
perror(argv[1]);
exit(1);
}
} else {
fputs("usage: crc32 [filename]", stderr);
exit(1);
}
do {
len = fread(msg, 1, BUFFER, f);
if (ferror(f)) {
perror(NULL);
exit(1);
}
v32 = crc32_calc(msg, len, v32);
} while (!feof(f));
fclose(f);
printf("%08lX\n", (unsigned long) ~v32);
}