建站行业最新消息,设计个人网页,网站简历导出,商务网站开发代码本文为博主 日月同辉#xff0c;与我共生#xff0c;csdn原创首发。希望看完后能对你有所帮助#xff0c;不足之处请指正#xff01;一起交流学习#xff0c;共同进步#xff01; 发布人#xff1a;日月同辉,与我共生_单片机-CSDN博客 欢迎你为独创博主日月同… 本文为博主 日月同辉与我共生csdn原创首发。希望看完后能对你有所帮助不足之处请指正一起交流学习共同进步 发布人日月同辉,与我共生_单片机-CSDN博客 欢迎你为独创博主日月同辉与我共生点赞❤❤❤关注收藏评论☺。 系列专栏 CSDN-单片机串口通信学习系列 我的格言是“尽最大努力做最好的自己 要转载请提前告知 版权声明本文为CSDN博主「日月同辉与我共生」的原创文章CSDN独一份。 目录
一、CRC效验简介
二、CRC应用广泛
三、校验优缺点
3.1优缺点-奇偶效验
3.2优缺点-异或效验
3.3优缺点-CRC效验
四、CRC效验
五、参考模型
六、crc算法
一、CRC效验简介
循环冗余校验码CRC是一种常用的、具有检错能力的校验码。循环冗余校验是指通过某种数学运算实现有效信息与校验位之间的循环校验。
这种编码基本思想是将要传送的信息M(X)表示为一个多项式L用L除以一个预先确定的多项式G(X)得到的余式就是所需的循环冗余校验码。如果余数不为0则说明数据在传输过程中出现了错误相反余数为0说明数据在传输过程中未发生错误。
二、CRC应用广泛 CRC的应用非常广泛包括但不限于以下领域 ⛄网络通信在网络通信中CRC被广泛用于检测数据传输过程中的错误。发送端将数据和 CRC一起发送给接收端接收端通过计算CRC来检查数据是否在传输过程中被损坏。 ⛄文件存储在文件存储中CRC可以用于检测文件的完整性。文件在传输或存储过程中可 能会被损坏CRC可以帮助我们检测出这种错误。 ⛄数据存储在数据存储中CRC可以用于检测数据的完整性。例如在数据库中CRC可 以用于检查存储的数据是否在存储过程中被更改。 ⛄硬件设计在硬件设计中CRC被用于检测硬件故障。例如在内存或CPU中CRC可以 用于检测存储单元或逻辑单元是否存在问题。 ⛄安全系统CRC也被用于一些安全系统中例如防火墙或入侵检测系统IDS以检测 异常流量或恶意攻击。
三、校验优缺点
3.1优缺点-奇偶效验
奇偶校验使用一个额外的二进制位校验位来确保数据中1的个数符合规定的奇偶性。例如如果要求数据中1的个数为奇数那么当数据中1的个数为偶数时需要在数据的末尾添加一个1使得总共有奇数个1。同样地如果要求数据中1的个数为偶数那么当数据中1的个数为奇数时需要在数据的末尾添加一个0使得总共有偶数个1。
奇偶校验的优点是简单易实现适用于检测单个位的错误。但是它无法检测出多位错误并且如果传输中出现两位以上的错误则无法检测出错误。此外奇偶校验需要额外的带宽来传输校验位对传输效率有一定影响。
3.2优缺点-异或效验
异或校验利用了异或运算的性质即当两个操作数的对应位相同时结果为0当两个操作数的对应位不同时结果为1。因此通过对数据的每个比特位进行异或运算可以得到一个校验码。在接收端将接收到的数据再次进行异或运算如果结果为0则说明数据没有被篡改否则说明数据可能被篡改。
它的优点是简单快速、无需额外的冗余位和带宽但缺点是只能检测到奇数位的错误。
3.3优缺点-CRC效验
CRC效验是一种广泛应用的数据校验方法具有检测错误能力强、适用于多种数据类型和传输方式、校验效率高等优点。然而CRC也存在一些缺点如计算复杂度高、需要添加冗余位、在出现多个错误时可能无法检测出所有错误等。
四、CRC效验 思路步骤 1.把生成多项式转换成二进制数。例如对于多项式GXX4X31它一共是5位最高位的幂次为4加1得到5根据多项式各项的含义可以得到它的二进制比特串为11001。 2.根据CRC校验码的位数和生成多项式的关系得出CRC校验码的位数为4校验码的位数比生成多项式的位数少1。 3.初始化CRC校验码的值为0并将其添加到信息后面。 4.依据“模2除法”计算CRC校验码。每次计算都是消除高次项然后移入新的数据再进行下一次计算直到所有的数据计算完成。 5.将计算出的余数替代CRC校验码初始值得到CRC校验码。 6.最终得到的CRC校验码就是数据在传输过程中需要携带的校验信息。 模2除法是一种在二进制下进行除法的计算方法其特点是在每一位的除法结果不影响其他位即不向上一位借位实际上就是异或。可以看下列例子↓ ↓ ↓ 例子
假设我们有一个数据帧data frame为1011001并且我们选择的生成多项式generator polynomial为X^5X^41对应的二进制数为11001。
因为CRC校验码的位数比生成多项式的位数6位总位数最高次幂1少1所以CRC校验码的位数为5。
1初始化CRC校验码为全0即00000。
2将数据帧与CRC校验码拼接起来得到新的数据序列101100100000。
3把101100100000以“模2除法”除于生成多项式11001计算。
4将结果01101代替101100100000后面的五位“00000”将新帧101100101101发送到接收端。
5新帧被接收端接收后接收端把新帧再用生成多项式11001以“模2除法”方式去除验证余数是否为0。如果结果为0则说明数据没有被篡改否则说明数据可能被篡改。 五、参考模型
CRC参考模型
CRC算法名称多项式公式宽度多项式初始值结果异或值输入值反转输出值反转CRC-4/ITUx4 x 14030000truetrueCRC-5/EPCx4 x3 15090900falsefalseCRC-5/ITUx5 x4 x2 15150000truetrueCRC-5/USBx5 x2 15051F1FtruetrueCRC-6/ITUx6 x 16030000truetrueCRC-7/MMCx7 x3 17090000falsefalseCRC-8x8 x2 x 18070000falsefalseCRC-8/ITUx8 x2 x 18070055falsefalseCRC-8/ROHCx8 x2 x 1807FF00truetrueCRC-8/MAXIMx8 x5 x4 18310000truetrueCRC-16/IBMx16 x15 x2 116800500000000truetrueCRC-16/MAXIMx16 x15 x2 11680050000FFFFtruetrueCRC-16/USBx16 x15 x2 1168005FFFFFFFFtruetrueCRC-16/MODBUSx16 x15 x2 1168005FFFF0000truetrueCRC-16/CCITTx16 x12 x5 116102100000000truetrueCRC-16/CCITT-FALSEx16 x12 x5 1161021FFFF0000falsefalseCRC-16/x5x16 x12 x5 1161021FFFFFFFFtruetrueCRC-16/XMODEMx16 x12 x5 116102100000000falsefalseCRC-16/DNPx16 x13 x12 x11 x10 x8 x6 x5 x2 1163D650000FFFFtruetrueCRC-32x32 x26 x23 x22 x16 x12 x11 x10 x8 x7 x5 x4 x2 x 13204C11DB7FFFFFFFFFFFFFFFFtruetrueCRC-32/BZIP2x32 x26 x23 x22 x16 x12 x11 x10 x8 x7 x5 x4 x2 x 13204C11DB7FFFFFFFFFFFFFFFFfalsefalseCRC-32/MPEG-2x32 x26 x23 x22 x16 x12 x11 x10 x8 x7 x5 x4 x2 x 13204C11DB7FFFFFFFF00000000falsefalse
六、crc算法
MODBUS通讯协议CRC16校验代码(读者可自行引用) CRC算法名称多项式公式宽度多项式初始值结果异或值输入值反转输出值反转 CRC-16/MODBUSx16 x15 x2 1168005FFFF0000truetrue /***********************CRC校验*************************/// CRC 高位字节值表
unsigned char code auchCRCHi[260] {
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
} ;
// CRC低位字节值表
unsigned char code auchCRCLo[260] {
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06,
0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD,
0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,
0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A,
0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4,
0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3,
0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4,
0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,
0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29,
0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED,
0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60,
0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67,
0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,
0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68,
0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E,
0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71,
0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92,
0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B,
0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B,
0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42,
0x43, 0x83, 0x41, 0x81, 0x80, 0x40
} ;
unsigned int crc16(unsigned char *puchMsg, unsigned int usDataLen)
{ unsigned char uchCRCHi 0xFF ; //*高CRC字节初始化 unsigned char uchCRCLo 0xFF ; //*低CRC字节初始化 unsigned long uIndex ; // CRC循环中的索引 while (usDataLen--) //传输消息缓冲区 { uIndex uchCRCHi ^ *puchMsg ; // 计算CRC uchCRCHi uchCRCLo ^ auchCRCHi[uIndex] ; uchCRCLo auchCRCLo[uIndex] ; } return (uchCRCHi 8 | uchCRCLo);
}STM系列/***********************CRC校验*************************/// CRC 高位字节值表
static const U8 auchCRCHi[260] {
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
} ;
// CRC低位字节值表
static const U8 auchCRCLo[260] {
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06,
0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD,
0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,
0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A,
0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4,
0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3,
0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4,
0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,
0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29,
0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED,
0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60,
0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67,
0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,
0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68,
0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E,
0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71,
0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92,
0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B,
0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B,
0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42,
0x43, 0x83, 0x41, 0x81, 0x80, 0x40
} ;
U16 crc16(U8 *puchMsg, U16 usDataLen)
{ U8 uchCRCHi 0xFF ; //*高CRC字节初始化 U8 char uchCRCLo 0xFF ; //*低CRC字节初始化 U32 uIndex ; // CRC循环中的索引 while (usDataLen--) //传输消息缓冲区 { uIndex uchCRCHi ^ *puchMsg ; // 计算CRC uchCRCHi uchCRCLo ^ auchCRCHi[uIndex]; uchCRCLo auchCRCLo[uIndex] ; } return (U16)(uchCRCHi 8 | uchCRCLo);
}亲爱的读者敬请期待下一文更精彩 一日不读书胸臆无佳想。我叫不白吃喜欢我的可以支持我博主名叫 日月同辉,与我共生https://blog.csdn.net/LIN___IT?typeblog