#include "check.h" //获取校验长度 uint8_t check_size(uint8_t type) { uint8_t size = 0; switch(type) { case CHECK_SUM8: case CHECK_XOR8: case CHECK_CRC8_MAXIM: size = 1; break; case CHECK_CRC16_MODBUS: size = 2; break; } return size; } //获取校验值 uint32_t check_value(check_t check, uint8_t *data) { uint32_t value = 0; //校验值 switch(check.type) { case CHECK_SUM8: value = CHECKSUM8(data+check.start, check.length); break; case CHECK_XOR8: value = XOR8(data+check.start, check.length); break; case CHECK_CRC8_MAXIM: value = CRC8_MAXIM(data+check.start, check.length); break; case CHECK_CRC16_MODBUS: value = CRC16_MODBUS(data+check.start, check.length); break; } return value; } //计算并比较校验 uint8_t check_cmp(check_t check, uint8_t *data) { if(check.length > 0) { uint8_t size = check_size(check.type); //校验长度 uint32_t value = check_value(check, data); //校验值 switch(size) { case 1: //1字节校验 if(data[check.index] == (value&0xFF)) { return 1; } break; case 2: //2字节校验 if((data[check.index] == (value&0xFF)) && (data[check.index+1] == ((value>>8)&0xFF))) { return 1; } break; } } return 0; } //计算并添加校验 void check_add(check_t check, uint8_t *data) { if(check.length > 0) { uint8_t size = check_size(check.type); //校验长度 uint32_t value = check_value(check, data); //校验值 switch(size) { case 1: //1字节校验 data[check.index] = value & 0xFF; break; case 2: //2字节校验 data[check.index] = value & 0xFF; data[check.index+1] = (value>>8) & 0xFF; break; } } } //校验和 uint8_t CHECKSUM8(const uint8_t *data, uint16_t length) { uint8_t sum = 0; while(length--) { sum += *data++; } return (sum); } //异或校验 uint8_t XOR8(const uint8_t *data, uint16_t length) { uint8_t x = 0; while(length--) { x ^= *data++; } return (x); } /************************************************* * CRC-8: X8+X2+X+1 * POLY: 0x07 * INIT: 0x00 * REFIN: FALSE * REFOUT: FALSE * XOROUT: 0x00 **************************************************/ uint8_t CRC8(const uint8_t *data, uint16_t length) { uint8_t crc = 0x00; uint8_t poly = 0x07; while(length--) { crc ^= *data++; for(uint8_t i = 0; i < 8; i++) { if(crc & 0x80) crc = (crc << 1) ^ poly; else crc = crc << 1; } } return (crc); } /************************************************* * CRC-8/ITU: X8+X2+X+1 * POLY: 0x07 * INIT: 0x00 * REFIN: FALSE * REFOUT: FALSE * XOROUT: 0x55 **************************************************/ uint8_t CRC8_ITU(const uint8_t *data, uint16_t length) { uint8_t crc = 0x00; uint8_t poly = 0x07; while(length--) { crc ^= *data++; for(uint8_t i = 0; i < 8; i++) { if(crc & 0x80) crc = (crc << 1) ^ poly; else crc = crc << 1; } } return (crc ^ 0x55); } /************************************************* * CRC-8/ROHC: X8+X2+X+1 * POLY: 0x07 * INIT: 0xFF * REFIN: TRUE * REFOUT: TRUE * XOROUT: 0x00 **************************************************/ uint8_t CRC8_ROHC(const uint8_t *data, uint16_t length) { uint8_t crc = 0xFF; uint8_t poly = 0xE0; //0x07字节颠倒后为0xE0 while(length--) { crc ^= *data++; for(uint8_t i = 0; i < 8; i++) { if(crc & 0x01) crc = (crc >> 1) ^ poly; else crc = crc >> 1; } } return (crc); } /************************************************* * CRC-8/MAXIM: X8+X2+X+1 * POLY: 0x31 * INIT: 0x00 * REFIN: TRUE * REFOUT: TRUE * XOROUT: 0x00 **************************************************/ uint8_t CRC8_MAXIM(const uint8_t *data, uint16_t length) { uint8_t crc = 0x00; uint8_t poly = 0x8C; //0x31字节颠倒后为0x8C while(length--) { crc ^= *data++; for(uint8_t i = 0; i < 8; i++) { if(crc & 0x01) crc = (crc >> 1) ^ poly; else crc = crc >> 1; } } return (crc); } /************************************************* * CRC-8: X8+X4+X3+X2+1 * POLY: 0x1D * INIT: 0x00 * REFIN: FALSE * REFOUT: FALSE * XOROUT: 0x00 **************************************************/ uint8_t CRC8_SAE(const uint8_t *data, uint16_t length) { uint8_t crc = 0x00; uint8_t poly = 0x1D; while(length--) { crc ^= *data++; for(uint8_t i = 0; i < 8; i++) { if(crc & 0x80) crc = (crc << 1) ^ poly; else crc = crc << 1; } } return (crc); } /************************************************* * CRC-16/CCITT: X16+X12+X5+1 * POLY: 0x1021 * INIT: 0x0000 * REFIN: TRUE * REFOUT: TRUE * XOROUT: 0x0000 **************************************************/ uint16_t CRC16_CCITT(const uint8_t *data, uint16_t length) { uint16_t crc = 0x0000; uint16_t poly = 0x8408; //0x1021字节颠倒后为0x8408 while(length--) { crc ^= *data++; for(uint8_t i = 0; i < 8; i++) { if(crc & 0x01) crc = (crc >> 1) ^ poly; else crc = crc >> 1; } } return (crc); } /************************************************* * CRC-16/CCITT-FALSE: X16+X12+X5+1 * POLY: 0x1021 * INIT: 0xFFFF * REFIN: FALSE * REFOUT: FALSE * XOROUT: 0x0000 **************************************************/ uint16_t CRC16_CCITT_FALSE(const uint8_t *data, uint16_t length) { uint16_t crc = 0xFFFF; uint16_t poly = 0x1021; while(length--) { crc ^= ((*data++) << 8); for(uint8_t i = 0; i < 8; i++) { if(crc & 0x8000) crc = (crc << 1) ^ poly; else crc = crc << 1; } } return (crc); } /************************************************* * CRC-16/XMODEM: X16+X12+X5+1 * POLY: 0x1021 * INIT: 0x0000 * REFIN: FALSE * REFOUT: FALSE * XOROUT: 0x0000 **************************************************/ uint16_t CRC16_XMODEM(const uint8_t *data, uint16_t length) { uint16_t crc = 0x0000; uint16_t poly = 0x1021; while(length--) { crc ^= ((*data++) << 8); for(uint8_t i = 0; i < 8; i++) { if(crc & 0x8000) crc = (crc << 1) ^ poly; else crc = crc << 1; } } return (crc); } /************************************************* * CRC-16/X25: X16+X12+X5+1 * POLY: 0x1021 * INIT: 0xFFFF * REFIN: TRUE * REFOUT: TRUE * XOROUT: 0xFFFF **************************************************/ uint16_t CRC16_X25(const uint8_t *data, uint16_t length) { uint16_t crc = 0xFFFF; uint16_t poly = 0x8408; //0x1021字节颠倒后为0x8408 while(length--) { crc ^= *data++; for(uint8_t i = 0; i < 8; i++) { if(crc & 0x01) crc = (crc >> 1) ^ poly; else crc = crc >> 1; } } return (crc^0xFFFF); } /************************************************* * CRC-16/MODBUS: X16+X12+X5+1 * POLY: 0x8005 * INIT: 0xFFFF * REFIN: TRUE * REFOUT: TRUE * XOROUT: 0x0000 **************************************************/ uint16_t CRC16_MODBUS(const uint8_t *data, uint16_t length) { uint16_t crc = 0xFFFF; uint16_t poly = 0xA001; //0x8005字节颠倒后为0xA001 while(length--) { crc ^= *data++; for(uint8_t i = 0; i < 8; i++) { if(crc & 0x01) crc = (crc >> 1) ^ poly; else crc = crc >> 1; } } return (crc); } /************************************************* * CRC-16/IBM: X16+X12+X5+1 * POLY: 0x8005 * INIT: 0x0000 * REFIN: TRUE * REFOUT: TRUE * XOROUT: 0x0000 **************************************************/ uint16_t CRC16_IBM(const uint8_t *data, uint16_t length) { uint16_t crc = 0x0000; uint16_t poly = 0xA001; //0x8005字节颠倒后为0xA001 while(length--) { crc ^= *data++; for(uint8_t i = 0; i < 8; i++) { if(crc & 0x01) crc = (crc >> 1) ^ poly; else crc = crc >> 1; } } return (crc); } /************************************************* * CRC-16/MAXIM: X16+X12+X5+1 * POLY: 0x8005 * INIT: 0x0000 * REFIN: TRUE * REFOUT: TRUE * XOROUT: 0xFFFF **************************************************/ uint16_t CRC16_MAXIM(const uint8_t *data, uint16_t length) { uint16_t crc = 0x0000; uint16_t poly = 0xA001; //0x8005字节颠倒后为0xA001 while(length--) { crc ^= *data++; for(uint8_t i = 0; i < 8; i++) { if(crc & 0x01) crc = (crc >> 1) ^ poly; else crc = crc >> 1; } } return (crc^0xFFFF); } /************************************************* * CRC-16/USB: X16+X12+X5+1 * POLY: 0x8005 * INIT: 0xFFFF * REFIN: TRUE * REFOUT: TRUE * XOROUT: 0xFFFF **************************************************/ uint16_t CRC16_USB(const uint8_t *data, uint16_t length) { uint16_t crc = 0xFFFF; uint16_t poly = 0xA001; //0x8005字节颠倒后为0xA001 while(length--) { crc ^= *data++; for(uint8_t i = 0; i < 8; i++) { if(crc & 0x01) crc = (crc >> 1) ^ poly; else crc = crc >> 1; } } return (crc^0xFFFF); } /************************************************* * CRC-16/NDP: X16+X12+X5+1 * POLY: 0x3D65 * INIT: 0x0000 * REFIN: TRUE * REFOUT: TRUE * XOROUT: 0xFFFF **************************************************/ uint16_t CRC16_NDP(const uint8_t *data, uint16_t length) { uint16_t crc = 0x0000; uint16_t poly = 0xA6BC; //0x3D65字节颠倒后为0xA6BC while(length--) { crc ^= *data++; for(uint8_t i = 0; i < 8; i++) { if(crc & 0x01) crc = (crc >> 1) ^ poly; else crc = crc >> 1; } } return (crc^0xFFFF); }