SAE-J1850汽车CAN总线CheckSum算法之CRC-8校验算法
摘要: CRC(Cyclic Redundancy Check),循环冗余校验
CRC算法将数据与多项式相除,得到的余数再与多项式相除,如此反复,所以叫循环冗余,最终得到一个和多项式位数相同的余数,作为校验码;
多项式决定了校验码的位数,根 ...
CRC(Cyclic Redundancy Check),循环冗余校验 CRC算法将数据与多项式相除,得到的余数再与多项式相除,如此反复,所以叫循环冗余,最终得到一个和多项式位数相同的余数,作为校验码; 多项式决定了校验码的位数,根据校验码位数不同,一般有CRC-4,CRC-8,CRC-16,CRC-32,CRC-64,CRC-128等,不同的多项式对错误的检测率有差别,CRC相关标准中推荐的多项式都是精心挑选的。 SAE-J1850中的CRC-8校验算法 SAE-J1850中推荐的CRC校验多项式为1Dh, 即:x^8+x^4+x^3+x^2+1; 多项式的最高位默认均为1,且在CRC-8算法中,最高位不使用,因此在多项式记录时去掉了最高位; 1Dh转化为二进制为11101b,最高位补1后为10011101b,二进制中的每一位,对应多项式中的系数; SAE-J1850中的CRC-8算法被AUTOSAR标准所引用,后者还推荐了另外一种多项式为2Fh(x^8+x^5+x^3+x^2+x^1+1)的CRC-8校验算法。 参见:https://www.autosar.org/fileadmin/user_upload/standards/classic/4-3/AUTOSAR_SWS_CRCLibrary.pdf SAE-J1850中的CRC-8校验算法嵌入式代码实现(C语言) u8 crc8(u8 *data, u8 length) //SAE-J1850 CRC-8 function { u8 t_crc; u8 f, b; t_crc = 0xFF; for (f = 0; f < length; f++) { t_crc ^= data[f]; for (b = 0; b < 8; b++) { if ((t_crc & 0x80) != 0) //最高位为1,需要异或 { t_crc <<= 1; t_crc ^= 0x1D; } else { t_crc <<= 1; } } } return ~t_crc; //按位非,相当于异或0xFF } 上述0xFF、0x1D、0xFF分别对应SAE-J1850中规定的Polynomial、Initial value、XOR value,如下图所示: 在线验证CRC-8校验算法有效性 推荐一个可以在线运行C代码的网页:https://c.runoob.com/compile/11/ 使用SAE-J1850中的示例,0x0F 0xAA 0x00 0x55,CRC为0x79; 验证代码如下: #include <stdio.h> typedef unsigned char u8; u8 crc8(u8 *data, u8 length) { u8 t_crc; u8 f, b; t_crc = 0xFF; for (f = 0; f < length; f++) { t_crc ^= data[f]; for (b = 0; b < 8; b++) { if ((t_crc & 0x80) != 0) { t_crc <<= 1; t_crc ^= 0x1D; } else { t_crc <<= 1; } } } return ~t_crc; } int main() { u8 data[4]={0x0F, 0xAA, 0x00, 0x55}; u8 length=4; u8 t_crc; t_crc=crc8(data,length); printf("\r\nCRC8=%02X\r\n", t_crc); } |