#include <stdio.h>
#include <stdint.h>
uint32_t crc_table[256];
/* Run this function previously */
void make_crc_table(void) {
for (uint32_t i = 0; i < 256; i++) {
uint32_t c = i;
for (int j = 0; j < 8; j++) {
c = (c & 1) ? (0xEDB88320 ^ (c >> 1)) : (c >> 1);
}
crc_table[i] = c;
}
}
uint32_t crc32_wikipedia(const uint8_t *buf, size_t len) {
uint32_t c = 0xFFFFFFFF;
for (size_t i = 0; i < len; i++) {
c = crc_table[(c ^ buf[i]) & 0xFF] ^ (c >> 8);
}
return c ^ 0xFFFFFFFF;
}
const uint32_t Polynomial = 0xEDB88320;
uint32_t crc32_bitwise(const void* data, size_t length, uint32_t previousCrc32 = 0) {
uint32_t crc = ~previousCrc32; // same as previousCrc32 ^ 0xFFFFFFFF
unsigned char* current = (unsigned char*) data;
while (length--) {
crc ^= *current++;
for (unsigned int j = 0; j < 8; j++)
if (crc & 1) crc = (crc >> 1) ^ Polynomial; else crc = crc >> 1;
}
return ~crc; // same as crc ^ 0xFFFFFFFF
}
int main()
{
make_crc_table();
printf("%08x\n", crc32_wikipedia((const uint8_t *)"abcdefghijklmnopqrstuvwxyz", 26));
printf("%08x\n", crc32_bitwise("abcdefghijklmnopqrstuvwxyz", 26, 0));
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRpbnQuaD4KIAoKdWludDMyX3QgY3JjX3RhYmxlWzI1Nl07CiAKLyogUnVuIHRoaXMgZnVuY3Rpb24gcHJldmlvdXNseSAqLwp2b2lkIG1ha2VfY3JjX3RhYmxlKHZvaWQpIHsKICAgIGZvciAodWludDMyX3QgaSA9IDA7IGkgPCAyNTY7IGkrKykgewogICAgICAgIHVpbnQzMl90IGMgPSBpOwogICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgODsgaisrKSB7CiAgICAgICAgICAgIGMgPSAoYyAmIDEpID8gKDB4RURCODgzMjAgXiAoYyA+PiAxKSkgOiAoYyA+PiAxKTsKICAgICAgICB9CiAgICAgICAgY3JjX3RhYmxlW2ldID0gYzsKICAgIH0KfQogCnVpbnQzMl90IGNyYzMyX3dpa2lwZWRpYShjb25zdCB1aW50OF90ICpidWYsIHNpemVfdCBsZW4pIHsKICAgIHVpbnQzMl90IGMgPSAweEZGRkZGRkZGOwogICAgZm9yIChzaXplX3QgaSA9IDA7IGkgPCBsZW47IGkrKykgewogICAgICAgIGMgPSBjcmNfdGFibGVbKGMgXiBidWZbaV0pICYgMHhGRl0gXiAoYyA+PiA4KTsKICAgIH0KICAgIHJldHVybiBjIF4gMHhGRkZGRkZGRjsKfQoKCgpjb25zdCB1aW50MzJfdCBQb2x5bm9taWFsID0gMHhFREI4ODMyMDsKCiB1aW50MzJfdCBjcmMzMl9iaXR3aXNlKGNvbnN0IHZvaWQqIGRhdGEsIHNpemVfdCBsZW5ndGgsIHVpbnQzMl90IHByZXZpb3VzQ3JjMzIgPSAwKSB7IAogICAgIHVpbnQzMl90IGNyYyA9IH5wcmV2aW91c0NyYzMyOyAvLyBzYW1lIGFzIHByZXZpb3VzQ3JjMzIgXiAweEZGRkZGRkZGIAogICAgIHVuc2lnbmVkIGNoYXIqIGN1cnJlbnQgPSAodW5zaWduZWQgY2hhciopIGRhdGE7IAogICAgIHdoaWxlIChsZW5ndGgtLSkgeyAKICAgICAgICAgY3JjIF49ICpjdXJyZW50Kys7IAogICAgICAgICBmb3IgKHVuc2lnbmVkIGludCBqID0gMDsgaiA8IDg7IGorKykgCiAgICAgICAgIGlmIChjcmMgJiAxKSBjcmMgPSAoY3JjID4+IDEpIF4gUG9seW5vbWlhbDsgZWxzZSBjcmMgPSBjcmMgPj4gMTsgCiAgICAgICAgIAogICAgIH0gCiAgICAgcmV0dXJuIH5jcmM7IC8vIHNhbWUgYXMgY3JjIF4gMHhGRkZGRkZGRiAKfSAKCgppbnQgbWFpbigpCnsKICAgIG1ha2VfY3JjX3RhYmxlKCk7CiAgICBwcmludGYoIiUwOHhcbiIsIGNyYzMyX3dpa2lwZWRpYSgoY29uc3QgdWludDhfdCAqKSJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5eiIsIDI2KSk7CiAgICBwcmludGYoIiUwOHhcbiIsIGNyYzMyX2JpdHdpc2UoImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6IiwgMjYsIDApKTsKfQ==