[ Home ]

Simple CRC32 C-code

Here is a simple implementation of the commonly used CRC32 checksum using the reverse polynomial 0xEDB88320. The algorithm is consistent with setting of all bits in the initial CRC, along with negation of the bit pattern of the final running CRC. The code has been tested against the CRC-routines in the PNG specification published by W3C.

/* Simple public domain implementation of the standard CRC32 checksum.
 * Outputs the checksum for each file given as a command line argument.
 * Invalid file names and files that cause errors are silently skipped.
 * The program reads from stdin if it is called with no arguments. */

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>

uint32_t crc32_for_byte(uint32_t r) {
  for(int j = 0; j < 8; ++j)
    r = (r & 1? 0: (uint32_t)0xEDB88320L) ^ r >> 1;
  return r ^ (uint32_t)0xFF000000L;
}

void crc32(const void *data, size_t n_bytes, uint32_t* crc) {
  static uint32_t table[0x100];
  if(!*table)
    for(size_t i = 0; i < 0x100; ++i)
      table[i] = crc32_for_byte(i);
  for(size_t i = 0; i < n_bytes; ++i)
    *crc = table[(uint8_t)*crc ^ ((uint8_t*)data)[i]] ^ *crc >> 8;
}

int main(int ac, char** av) {
  FILE *fp;
  char buf[1L << 15];
  for(int i = ac > 1; i < ac; ++i)
    if((fp = i? fopen(av[i], "rb"): stdin)) { 
      uint32_t crc = 0;
      while(!feof(fp) && !ferror(fp))
        crc32(buf, fread(buf, 1, sizeof(buf), fp), &crc);
      if(!ferror(fp))
        printf("%08x%s%s\n", crc, ac > 2? "\t": "", ac > 2? av[i]: "");
      if(i)
        fclose(fp);
    }
  return 0;
}
crc32_simple.c

Here is similar but faster implementation for compilation with an optimizer that performs loop unwinding: crc32_fast.c for little endian architectures. It only works for little endian architectures because of the way it uses pointer-reinterpretation casts.

Last and least, the silly and mildly obfuscated crc32-implementation silly.c.


Updated September 2012