Skip to content

Instantly share code, notes, and snippets.

@steakknife
Last active Sep 26, 2020
Embed
What would you like to do?
Correct, constant-time CRC-16-IBM/CRC-16-ARC implementation in C99
/*
From https://reveng.sourceforge.io/crc-catalogue/16.htm#crc.cat-bits.16
CRC-16/ARC
width=16 poly=0x8005 init=0x0000 refin=true refout=true xorout=0x0000 check=0xbb3d residue=0x0000 name="CRC-16/ARC"
Class: attested
Alias: ARC, CRC-16, CRC-16/LHA, CRC-IBM
*/
#include <stdint.h>
#include <string.h>
#include <stdio.h>
static const uint16_t crc16_ibm_tbl[2] = { 0x0000, 0xA001 };
#define CRC16_IBM_ROUND crc = (crc >> 1) ^ crc16_ibm_tbl[crc & 1]
uint16_t
crc16_ibm(const void *x, size_t sz) {
const uint8_t *d = (const uint8_t *)x;
uint16_t crc = 0;
if (!x) return 0;
while (sz--) {
crc ^= *d++;
CRC16_IBM_ROUND; CRC16_IBM_ROUND; CRC16_IBM_ROUND; CRC16_IBM_ROUND;
CRC16_IBM_ROUND; CRC16_IBM_ROUND; CRC16_IBM_ROUND; CRC16_IBM_ROUND;
}
return crc;
}
int
main(int argc, char** argv) {
if (argc != 2) return 1;
uint16_t crc = crc16_ibm((const void *)argv[1], strlen(argv[1]));
printf("CRC-16-IBM %04X\n", crc);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment