#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));
}