CHG: refactor CRC16 algos. This is a big change, most likely some parts broke, hard to test it all.

This commit is contained in:
iceman1001 2018-02-01 15:19:47 +01:00
commit 52d69ed4ee
35 changed files with 512 additions and 674 deletions

View file

@ -24,14 +24,14 @@ void init_table(CrcType_t ct) {
crc_type = ct;
switch (ct) {
case CRC_14A:
case CRC_14B:
case CRC_15:
case CRC_15_ICLASS: generate_table(CRC16_POLY_CCITT, true); break;
case CRC_14443_A:
case CRC_14443_B:
case CRC_15693:
case CRC_ICLASS: generate_table(CRC16_POLY_CCITT, true); break;
case CRC_FELICA: generate_table(CRC16_POLY_CCITT, false); break;
case CRC_LEGIC: generate_table(CRC16_POLY_LEGIC, true); break;
case CRC_DNP: generate_table(CRC16_POLY_DNP, true); break;
case CRC_CCITT: generate_table(CRC16_POLY_CCITT, false); break;
case CRC_KERMIT: generate_table(CRC16_POLY_CCITT, true); break;
default:
crc_table_init = false;
crc_type = CRC_NONE;
@ -97,7 +97,7 @@ uint16_t crc16_fast(uint8_t const *d, size_t n, uint16_t initval, bool refin, bo
return crc;
}
// bit looped solution
// bit looped solution TODO REMOVED
uint16_t update_crc16_ex( uint16_t crc, uint8_t c, uint16_t polynomial ) {
uint16_t i, v, tmp = 0;
@ -148,40 +148,88 @@ uint16_t crc16(uint8_t const *d, size_t length, uint16_t remainder, uint16_t pol
void compute_crc(CrcType_t ct, const uint8_t *d, size_t n, uint8_t *first, uint8_t *second) {
// can't calc a crc on less than 3 byte. (1byte + 2 crc bytes)
if ( n < 3 ) return;
// can't calc a crc on less than 1 byte
if ( n == 0 ) return;
init_table(ct);
uint16_t crc = 0;
switch (ct) {
case CRC_14A: crc = crc16_a(d, n); break;
case CRC_14B:
case CRC_15: crc = crc16_x25(d, n); break;
case CRC_15_ICLASS: crc = crc16_iclass(d, n); break;
case CRC_14443_A: crc = crc16_a(d, n); break;
case CRC_14443_B:
case CRC_15693: crc = crc16_x25(d, n); break;
case CRC_ICLASS: crc = crc16_iclass(d, n); break;
case CRC_FELICA:crc = crc16_xmodem(d, n); break;
//case CRC_LEGIC:
case CRC_DNP: crc = crc16_dnp(d, n); break;
case CRC_CCITT: crc = crc16_ccitt(d, n); break;
case CRC_KERMIT: crc = crc16_kermit(d, n); break;
default: break;
}
*first = (crc & 0xFF);
*second = ((crc >> 8) & 0xFF);
}
uint16_t crc(CrcType_t ct, const uint8_t *d, size_t n) {
//poly=0x1021 init=0xffff refin=false refout=false xorout=0x0000 check=0x29b1 residue=0x0000 name="CRC-16/CCITT-FALSE"
// can't calc a crc on less than 3 byte. (1byte + 2 crc bytes)
if ( n < 3 ) return 0;
init_table(ct);
switch (ct) {
case CRC_14443_A: return crc16_a(d, n);
case CRC_14443_B:
case CRC_15693: return crc16_x25(d, n);
case CRC_ICLASS: return crc16_iclass(d, n);
case CRC_FELICA: return crc16_xmodem(d, n);
//case CRC_LEGIC:
case CRC_CCITT: return crc16_ccitt(d, n);
case CRC_KERMIT: return crc16_kermit(d, n);
default: break;
}
return 0;
}
// check CRC
// ct crc type
// d buffer with data
// n length (including crc)
//
// This function uses the message + crc bytes in order to compare the "residue" afterwards.
// crc16 algos like CRC-A become 0x000
// while CRC-15693 become 0x0F47
// If calculated with crc bytes, the residue should be 0xF0B8
bool check_crc(CrcType_t ct, const uint8_t *d, size_t n) {
// can't calc a crc on less than 3 byte. (1byte + 2 crc bytes)
if ( n < 3 ) return false;
init_table(ct);
switch (ct) {
case CRC_14443_A: return (crc16_a(d, n) == 0);
case CRC_14443_B: return (crc16_x25(d, n) == X25_CRC_CHECK);
case CRC_15693: return (crc16_x25(d, n) == X25_CRC_CHECK);
case CRC_ICLASS: return (crc16_iclass(d, n) == 0);
case CRC_FELICA: return (crc16_xmodem(d, n) == 0);
//case CRC_LEGIC:
case CRC_CCITT: return (crc16_ccitt(d, n) == 0);
default: break;
}
return false;
}
// poly=0x1021 init=0xffff refin=false refout=false xorout=0x0000 check=0x29b1 residue=0x0000 name="CRC-16/CCITT-FALSE"
uint16_t crc16_ccitt(uint8_t const *d, size_t n) {
return crc16_fast(d, n, 0xffff, false, false);
}
// FDX-B ISO11784/85) uses KERMIT
//poly=0x1021 init=0x0000 refin=true refout=true xorout=0x0000 name="KERMIT"
// poly=0x1021 init=0x0000 refin=true refout=true xorout=0x0000 name="KERMIT"
uint16_t crc16_kermit(uint8_t const *d, size_t n) {
return crc16_fast(d, n, 0x0000, true, true);
}
// FeliCa uses XMODEM
//poly=0x1021 init=0x0000 refin=false refout=false xorout=0x0000 name="XMODEM"
// poly=0x1021 init=0x0000 refin=false refout=false xorout=0x0000 name="XMODEM"
uint16_t crc16_xmodem(uint8_t const *d, size_t n) {
return crc16_fast(d, n, 0x0000, false, false);
}
@ -190,14 +238,14 @@ uint16_t crc16_xmodem(uint8_t const *d, size_t n) {
// ISO 15693,
// ISO 14443 CRC-B
// ISO/IEC 13239 (formerly ISO/IEC 3309)
//poly=0x1021 init=0xffff refin=true refout=true xorout=0xffff name="X-25"
// poly=0x1021 init=0xffff refin=true refout=true xorout=0xffff name="X-25"
uint16_t crc16_x25(uint8_t const *d, size_t n) {
uint16_t crc = crc16_fast(d, n, 0xffff, true, true);
crc = ~crc;
return crc;
}
// CRC-A (14443-3)
//poly=0x1021 init=0xc6c6 refin=true refout=true xorout=0x0000 name="CRC-A"
// CRC-A (14443-3)
// poly=0x1021 init=0xc6c6 refin=true refout=true xorout=0x0000 name="CRC-A"
uint16_t crc16_a(uint8_t const *d, size_t n) {
return crc16_fast(d, n, 0xC6C6, true, true);
}
@ -216,20 +264,3 @@ uint16_t crc16_legic(uint8_t const *d, size_t n, uint8_t uidcrc) {
uint16_t initial = uidcrc << 8 | uidcrc;
return crc16_fast(d, n, initial, true, true);
}
// poly=0x3d65 init=0x0000 refin=true refout=true xorout=0xffff check=0xea82 name="CRC-16/DNP"
uint16_t crc16_dnp(uint8_t const *d, size_t n) {
uint16_t crc = crc16_fast(d, n, 0, true, true);
crc = ~crc;
return crc;
}
// -----------------CHECK functions.
bool check_crc16_ccitt(uint8_t const *d, size_t n) {
if (n < 3) return false;
uint16_t crc = crc16_ccitt(d, n - 2);
if ((( crc & 0xff ) == d[n-2]) && (( crc >> 8 ) == d[n-1]))
return true;
return false;
}