Merge remote-tracking branch 'tiny_crc32/master'
This commit is contained in:
commit
93f7ce654d
1 changed files with 60 additions and 0 deletions
60
crc32.c
Normal file
60
crc32.c
Normal 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);
|
||||
}
|
Loading…
Reference in a new issue