// c16.c - CRC16 with start 0xFFFF and POLYNOMIAL 0x1021 as used in PromptPay

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

#define CRC_START 0xFFFF

uint16_t crc16(const uint8_t *data) {
	uint16_t crc = CRC_START;
	uint32_t len = strlen(data);
	uint8_t x;
	// Implicit CRC_POLYNOMIAL 0x1021
	while (len--) {
		x = crc >> 8 ^ *data++;
		x ^= x>>4;
		crc = (crc << 8) ^ (x << 12) ^ (x << 5) ^ x;
	}
	return crc;
}

int main(int argc, char *argv[]) {
	uint8_t *data = "";
	if (argc > 1)
		data = argv[1];
	printf("%04X '%s'\n", crc16(data), data);
}
