chg: most of the crc16 works.

ISO14443 crc A  = crc16_a
ISO14443 crc B  = ...
ISO15693 crc    = crc16_x25
This commit is contained in:
iceman1001 2018-01-28 10:59:57 +01:00
commit e5804645f1
2 changed files with 96 additions and 27 deletions

View file

@ -7,44 +7,95 @@
//-----------------------------------------------------------------------------
#include "crc16.h"
#define CRC16_POLY_CCITT 0x1021
#define CRC16_POLY 0x8408
uint16_t update_crc16_ex( uint16_t crc, uint8_t c, uint16_t polynomial ) {
uint16_t i, v, tmp = 0;
uint16_t update_crc16( uint16_t crc, unsigned char c ) {
uint16_t i, v, tcrc = 0;
v = (crc ^ c) & 0xff;
for (i = 0; i < 8; i++) {
tcrc = ( (tcrc ^ v) & 1 ) ? ( tcrc >> 1 ) ^ CRC16_POLY : tcrc >> 1;
v >>= 1;
}
return ((crc >> 8) ^ tcrc) & 0xffff;
v = (crc ^ c) & 0xff;
for (i = 0; i < 8; i++) {
if ( (tmp ^ v) & 1 )
tmp = ( tmp >> 1 ) ^ polynomial;
else
tmp >>= 1;
v >>= 1;
}
return ((crc >> 8) ^ tmp) & 0xffff;
}
uint16_t update_crc16( uint16_t crc, uint8_t c ) {
return update_crc16_ex( crc, c, CRC16_POLY_CCITT);
}
uint16_t crc16(uint8_t const *message, int length, uint16_t remainder, uint16_t polynomial) {
// two ways.
// msb or lsb loop.
//
uint16_t crc16(uint8_t const *d, int length, uint16_t remainder, uint16_t polynomial, bool refin, bool refout) {
if (length == 0)
return (~remainder);
uint8_t c;
for (uint32_t i = 0; i < length; ++i) {
remainder ^= (message[i] << 8);
for (uint8_t bit = 8; bit > 0; --bit) {
c = d[i];
if (refin) c = reflect8(c);
// xor in at msb
remainder ^= (c << 8);
// 8 iteration loop
for (uint8_t j = 8; j; --j) {
if (remainder & 0x8000) {
remainder = (remainder << 1) ^ polynomial;
} else {
remainder = (remainder << 1);
remainder <<= 1;
}
}
}
/*
c = (c ^ (uint8_t)(remainder & 0x00FF));
c = (c ^ (c << 4));
remainder = (remainder >> 8) ^ ((uint16_t) c << 8) ^ ((uint16_t) c << 3) ^ ((uint16_t) c >> 4);
*/
}
if (refout)
remainder = reflect16(remainder);
return remainder;
}
uint16_t crc16_ccitt(uint8_t const *message, int length) {
return crc16(message, length, 0xffff, CRC16_POLY_CCITT);
uint16_t crc16_ccitt(uint8_t const *d, int n) {
return crc16(d, n, 0xffff, CRC16_POLY_CCITT, false, false);
}
//poly=0x1021 init=0x0000 refin=true refout=true xorout=0x0000 name="KERMIT"
uint16_t crc16_ccitt_kermit(uint8_t const *message, int length){
return crc16_kermit(message, length);
}
uint16_t crc16_kermit(uint8_t const *d, int n) {
return crc16(d, n, 0x0000, CRC16_POLY_CCITT, true, true);
}
//FeliCa uses XMODEM
//poly=0x1021 init=0x0000 refin=false refout=false xorout=0x0000 name="XMODEM"
uint16_t crc16_xmodem(uint8_t const *d, int n) {
return crc16(d, n, 0x0000, CRC16_POLY_CCITT, false, false);
}
//ISO 15693 uses X-25, CRC_B (or 14443-3 )
//poly=0x1021 init=0xffff refin=true refout=true xorout=0xffff name="X-25"
uint16_t crc16_x25(uint8_t const *d, int n) {
uint16_t crc = crc16(d, n, 0xffff, CRC16_POLY_CCITT, true, true);
crc ^= 0xFFFF;
return crc;
}
//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, int n) {
return crc16(d, n, 0xc6c6, 0x1021, true, true);
}
uint16_t crc16_ccitt_kermit(uint8_t const *message, int length) {
uint16_t val = crc16(message, length, 0x0000, CRC16_POLY_CCITT);
return SwapBits(val, 16);
}
bool check_crc16_ccitt(uint8_t const *d, int 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;
}

View file

@ -11,8 +11,26 @@
#include <stdint.h>
#include "util.h" // SwapBits
unsigned short update_crc16(unsigned short crc, unsigned char c);
uint16_t crc16(uint8_t const *message, int length, uint16_t remainder, uint16_t polynomial);
#define CRC16_POLY_CCITT 0x1021
#define CRC16_POLY 0x8408
uint16_t update_crc16_ex( uint16_t crc, uint8_t c, uint16_t polynomial );
uint16_t update_crc16(uint16_t crc, uint8_t c);
uint16_t crc16(uint8_t const *message, int length, uint16_t remainder, uint16_t polynomial, bool refin, bool refout);
uint16_t crc16_ccitt(uint8_t const *message, int length);
uint16_t crc16_ccitt_kermit(uint8_t const *message, int length);
uint16_t crc16_kermit(uint8_t const *message, int length);
uint16_t crc16_xmodem(uint8_t const *d, int n);
uint16_t crc16_x25(uint8_t const *d, int n);
uint16_t crc16_a(uint8_t const *d, int n);
bool check_crc16_ccitt(uint8_t const *d, int n);
//felica imp
void felica_test();
void init_crcccitt_tab( void );
uint16_t update_crc_ccitt( uint16_t crc,uint8_t c );
#endif