#include "crc_lib.h" static uint8_t CRC_4_ITU(uint8_t *data, uint8_t len); static uint8_t CRC_5_EPC(uint8_t *data, uint8_t len); static uint8_t CRC_5_ITU(uint8_t *data, uint8_t len); static uint8_t CRC_5_USB(uint8_t *data, uint8_t len); static uint8_t CRC_6_ITU(uint8_t *data, uint8_t len); static uint8_t CRC_7_MMC(uint8_t *data, uint8_t len); static uint8_t CRC_8(uint8_t *data, uint8_t len); static uint8_t CRC_8_ITU(uint8_t *data, uint8_t len); static uint8_t CRCC_8_ROHC(uint8_t *data, uint8_t len); static uint8_t CRC_8_MAXIM(uint8_t *data, uint8_t len); static uint16_t CRC_16_IBM(uint8_t *data, uint8_t len); static uint16_t CRC_16_MAXIM(uint8_t *data, uint8_t len); static uint16_t CRC_16_USB(uint8_t *data, uint8_t len); static uint16_t CRC_16_MODBUS(uint8_t *data, uint8_t len); static uint16_t CRC_16_CCITT(uint8_t *data, uint8_t len); static uint16_t CRC_16_CCITT_FALSE(uint8_t *data, uint8_t len); static uint16_t CRC_16_X25(uint8_t *data, uint8_t len); static uint16_t CRC_16_XMODEM(uint8_t *data, uint8_t len); static uint16_t CRC_16_DNP(uint8_t *data, uint8_t len); static uint32_t CRC_32(uint8_t *data, uint8_t len); static uint32_t CRC_32_MPEG_2(uint8_t *data, uint8_t len); FuncionTable crc_list = { .CRC_4_ITU = CRC_4_ITU, .CRC_5_EPC = CRC_5_EPC, .CRC_5_ITU = CRC_5_ITU, .CRC_5_USB = CRC_5_USB, .CRC_6_ITU = CRC_6_ITU, .CRC_7_MMC = CRC_7_MMC, .CRC_8 = CRC_8, .CRC_8_ITU = CRC_8_ITU, .CRCC_8_ROHC = CRCC_8_ROHC, .CRC_8_MAXIM = CRC_8_MAXIM, .CRC_16_IBM = CRC_16_IBM, .CRC_16_MAXIM = CRC_16_MAXIM, .CRC_16_USB = CRC_16_USB, .CRC_16_MODBUS = CRC_16_MODBUS, .CRC_16_CCITT = CRC_16_CCITT, .CRC_16_CCITT_FALSE = CRC_16_CCITT_FALSE, .CRC_16_X25 = CRC_16_X25, .CRC_16_XMODEM = CRC_16_XMODEM, .CRC_16_DNP = CRC_16_DNP, .CRC_32 = CRC_32, .CRC_32_MPEG_2 = CRC_32_MPEG_2, }; static uint8_t CRC_4_ITU(uint8_t *data, uint8_t len) { uint8_t i; uint8_t crc = 0; while(len--) { crc ^= *data++; for (i = 0; i < 8; ++i) { if (crc & 1) crc = (crc >> 1) ^ 0x0C; else crc = (crc >> 1); } } return crc & 0x0F; } static uint8_t CRC_5_EPC(uint8_t *data, uint8_t len) { uint8_t i; uint8_t crc = 0x48; while(len--) { crc ^= *data++; for ( i = 0; i < 8; i++ ) { if ( crc & 0x80 ) crc = (crc << 1) ^ 0x48; else crc <<= 1; } } return (crc >> 3) & 0x1F; } static uint8_t CRC_5_ITU(uint8_t *data, uint8_t len) { uint8_t i; uint8_t crc = 0; while(len--) { crc ^= *data++; for (i = 0; i < 8; ++i) { if (crc & 1) crc = (crc >> 1) ^ 0x15; else crc = (crc >> 1); } } return crc & 0x1F; } static uint8_t CRC_5_USB(uint8_t *data, uint8_t len) { uint8_t i; uint8_t crc = 0x1F; while(len--) { crc ^= *data++; for (i = 0; i < 8; ++i) { if (crc & 1) crc = (crc >> 1) ^ 0x14; else crc = (crc >> 1); } } return crc ^ 0x1F; } static uint8_t CRC_6_ITU(uint8_t *data, uint8_t len) { uint8_t i; uint8_t crc = 0; while(len--) { crc ^= *data++; for (i = 0; i < 8; ++i) { if (crc & 1) crc = (crc >> 1) ^ 0x30; else crc = (crc >> 1); } } return crc & 0x3F; } static uint8_t CRC_7_MMC(uint8_t *data, uint8_t len) { uint8_t i; uint8_t crc = 0; while(len--) { crc ^= *data++; for ( i = 0; i < 8; i++ ) { if ( crc & 0x80 ) crc = (crc << 1) ^ 0x12; else crc <<= 1; } } return (crc >> 1) & 0x7F; } static uint8_t CRC_8(uint8_t *data, uint8_t len) { uint8_t i; uint8_t crc = 0; while(len--) { crc ^= *data++; for ( i = 0; i < 8; i++ ) { if ( crc & 0x80 ) crc = (crc << 1) ^ 0x07; else crc <<= 1; } } return crc; } static uint8_t CRC_8_ITU(uint8_t *data, uint8_t len) { uint8_t i; uint8_t crc = 0; while(len--) { crc ^= *data++; for ( i = 0; i < 8; i++ ) { if ( crc & 0x80 ) crc = (crc << 1) ^ 0x07; else crc <<= 1; } } return crc ^ 0x55; } static uint8_t CRCC_8_ROHC(uint8_t *data, uint8_t len) { uint8_t i; uint8_t crc = 0xFF; while(len--) { crc ^= *data++; for (i = 0; i < 8; ++i) { if (crc & 1) crc = (crc >> 1) ^ 0xE0; else crc = (crc >> 1); } } return crc; } static uint8_t CRC_8_MAXIM(uint8_t *data, uint8_t len) { uint8_t i; uint8_t crc = 0; while(len--) { crc ^= *data++; for (i = 0; i < 8; i++) { if (crc & 1) crc = (crc >> 1) ^ 0x8C; else crc >>= 1; } } return crc; } static uint16_t CRC_16_IBM(uint8_t *data, uint8_t len) { uint8_t i; uint16_t crc = 0; while(len--) { crc ^= *data++; for (i = 0; i < 8; ++i) { if (crc & 1) crc = (crc >> 1) ^ 0xA001; else crc = (crc >> 1); } } return crc; } static uint16_t CRC_16_MAXIM(uint8_t *data, uint8_t len) { uint8_t i; uint16_t crc = 0; while(len--) { crc ^= *data++; for (i = 0; i < 8; ++i) { if (crc & 1) crc = (crc >> 1) ^ 0xA001; else crc = (crc >> 1); } } return ~crc; } static uint16_t CRC_16_USB(uint8_t *data, uint8_t len) { uint8_t i; uint16_t crc = 0xffff; while(len--) { crc ^= *data++; for (i = 0; i < 8; ++i) { if (crc & 1) crc = (crc >> 1) ^ 0xA001; else crc = (crc >> 1); } } return ~crc; } static uint16_t CRC_16_MODBUS(uint8_t *data, uint8_t len) { uint16_t crc = 0xFFFF; uint8_t i, j; for (j=0; j < len; j++) { crc=crc ^* data++; for (i = 0; i < 8; i++) { if((crc & 0x0001) > 0) { crc = crc >> 1; crc = crc ^ 0xa001; }else { crc = crc >> 1; } } } return crc; } static uint16_t CRC_16_CCITT(uint8_t *data, uint8_t len) { uint8_t i; uint16_t crc = 0; while(len--) { crc ^= *data++; for (i = 0; i < 8; ++i) { if (crc & 1) crc = (crc >> 1) ^ 0x8408; else crc = (crc >> 1); } } return crc; } static uint16_t CRC_16_CCITT_FALSE(uint8_t *data, uint8_t len) { uint8_t i; uint16_t crc = 0xffff; while(len--) { crc ^= (uint16_t)(*data++) << 8; for (i = 0; i < 8; ++i) { if ( crc & 0x8000 ) crc = (crc << 1) ^ 0x1021; else crc <<= 1; } } return crc; } static uint16_t CRC_16_X25(uint8_t *data, uint8_t len) { uint8_t i; uint16_t crc = 0xffff; while(len--) { crc ^= *data++; for (i = 0; i < 8; ++i) { if (crc & 1) crc = (crc >> 1) ^ 0x8408; else crc = (crc >> 1); } } return ~crc; } static uint16_t CRC_16_XMODEM(uint8_t *data, uint8_t len) { uint8_t i; uint16_t crc = 0; while(len--) { crc ^= (uint16_t)(*data++) << 8; for (i = 0; i < 8; ++i) { if ( crc & 0x8000 ) crc = (crc << 1) ^ 0x1021; else crc <<= 1; } } return crc; } static uint16_t CRC_16_DNP(uint8_t *data, uint8_t len) { uint8_t i; uint16_t crc = 0; while(len--) { crc ^= *data++; for (i = 0; i < 8; ++i) { if (crc & 1) crc = (crc >> 1) ^ 0xA6BC; else crc = (crc >> 1); } } return ~crc; } static uint32_t CRC_32(uint8_t *data, uint8_t len) { uint8_t i; uint32_t crc = 0xffffffff; while(len--) { crc ^= *data++; for (i = 0; i < 8; ++i) { if (crc & 1) crc = (crc >> 1) ^ 0xEDB88320; else crc = (crc >> 1); } } return ~crc; } static uint32_t CRC_32_MPEG_2(uint8_t *data, uint8_t len) { uint8_t i; uint32_t crc = 0xffffffff; while(len--) { crc ^= (uint32_t)(*data++) << 24; for (i = 0; i < 8; ++i) { if ( crc & 0x80000000 ) crc = (crc << 1) ^ 0x04C11DB7; else crc <<= 1; } } return crc; }