summaryrefslogtreecommitdiff
path: root/libmkv/nut-crc32.c
blob: e81c5d7492346feb9adf2881e23bd74be2877b1e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#define _GNU_SOURCE /* for error() */
#include <errno.h>  /* for errno */
#include <error.h>  /* for error() */
#include <stdint.h> /* for uint{n}_t */
#include <stdio.h>  /* for printf() */
#include <unistd.h> /* for read() */

void nut_crc32_init(uint32_t *crc) {
	/* "Starting value is zero."  */
	*crc = 0;
}

void nut_crc32_write(uint32_t *crc, uint8_t *dat, size_t len) {
	/* "Generator polynomial is 0x104C11DB7."  */
	static const uint32_t table[16] = {
		0x00000000, 0x04C11DB7, 0x09823B6E, 0x0D4326D9,
		0x130476DC, 0x17C56B6B, 0x1A864DB2, 0x1E475005,
		0x2608EDB8, 0x22C9F00F, 0x2F8AD6D6, 0x2B4BCB61,
		0x350C9B64, 0x31CD86D3, 0x3C8EA00A, 0x384FBDBD,
	};

	while (len--) {
		*crc ^= *dat++ << 24;
		*crc = (*crc<<4) ^ table[*crc>>28];
		*crc = (*crc<<4) ^ table[*crc>>28];
	}
}

int main() {
	uint32_t crc;
	uint8_t  buf[128];

	nut_crc32_init(&crc);

	size_t tot = 0;
	for (;;) {
		ssize_t n = read(0, buf, sizeof(buf));
		if (n <= 0)
			break;
		nut_crc32_write(&crc, buf, n);
		tot += n;
	}
	printf("crc32 = 0x%08x ; size = %zu\n", crc, tot);
	if (errno)
		error(1, errno, "read");
	return 0;
}