CRC校验记录

主内容,转载的。
原文链接:https://blog.csdn.net/m0_37105371/article/details/89363473

CRC16的算法原理:
1、根据CRC16的标准选择初值CRCLn的值。
2、将数据的第一个字节与CRCLn的高8位异或。
3、判断最高位,若该位为0,左移1位,若为1左移一位再与多项式Hex码异或。
4、重复3直至8个位全部移位计算结束。
5、重复将所有输入数据操作完成以上步骤,所得的16位数即为16位CRC校验码。
常见的几组CRC公式:
1、CRC16/IBM 或 CRC16/ARC 或 CRC16/LHA:
公式:x16+x15+x2+1
宽度:16
Poly值:0x8005
初始值:0x0000
基准输入:true
基准输出:true
标志位:0x0000

2、CRC16/MAXIM:
公式:x16+x15+x2+1
宽度:16
Poly值:0x8005
初始值:0x0000
基准输入:true
基准输出:true
标志位:0xFFFF

3、CRC16/USB:
公式:x16+x15+x2+1
宽度:16
Poly值:0x8005
初始值:0xFFFF
基准输入:true
基准输出:true
标志位:0xFFFF

4、CRC16/MODBUS(最常见):
公式:x16+x15+x2+1
宽度:16
Poly值:0x8005
初始值:0x0000
基准输入:true
基准输出:true
标志位:0x0000

5、CRC16/CCITT 或 CRC-CCITT 或CRC16/CCITT-TRUE或 CRC16/KERMIT:
公式:x16+x15+x5+1
宽度:16
Poly值:0x1021
初始值:0x0000
基准输入:true
基准输出:true
标志位:0x0000

6、 CRC16/CCITT-FALSE:
公式:x16+x15+x5+1
宽度:16
Poly值:0x1021
初始值:0xFFFF
基准输入:false
基准输出:false
标志位:0x0000

7、CRC16/X25:
公式:x16+x15+x5+1
宽度:16
Poly值:0x1021
初始值:0x0000
基准输入:true
基准输出:true
标志位:0xFFFF

8、CRC16/XMODEM 或 CRC16/ZMODEM 或 CRC16/ACORN:
公式:x16+x15+x5+1
宽度:16
Poly值:0x1021
初始值:0x0000
基准输入:false
基准输出:false
标志位:0x0000

9、CRC16/DNP:
公式:x16+x13+x12+x11+x10+x8+x6+x5+x2+1
宽度:16
Poly值:0x3D65
初始值:0x0000
基准输入:true
基准输出:true
标志位:0xFFFF
使用:M-Bus, ect

关于数据位序:如果我们的机器是小端模式(低位在后,高位在前),而数据输入的要求是低位在前高位在后时,就需要对数据顺序进行反转。

多项式的值是如果计算的:
以多项式:x16 + x12 + x5 + 1 为例
x16表示第16位为1,x12表示第12位为1,x5表示第5位为1
(1<<16) | (1<<12) | (1<<5) | 1 = 1 0001 000 0010 0001 = 0x1 1021
CRC16只取上面计算值的低16位所以最终结果为0x1021。

然后按上面及查的资料,测试了下面的代码,验证成功。

#include <iostream>
unsigned char test[5] = { 0x40,0x00,0x01,0x30, };//0x4414 校验码
unsigned char len = 5;
unsigned long crc_code = 0x18005;
unsigned long crc_hignbit = 0x10000;
int main()
{
        unsigned long temp = 0;
        unsigned int crc;
        unsigned char i;
        unsigned char* ptr = test;
        unsigned char len_temp = len;
        while (len_temp--) {
            for (i = 0x80; i != 0; i = i >> 1) {
                temp = temp * 2;
                if ((temp & crc_hignbit) != 0)
                    temp = temp ^ crc_code;

                if ((*ptr & i) != 0)
                    temp = temp ^ (crc_hignbit ^ crc_code);

            }
            ptr++;
        }
        crc = temp;
        printf("crc为: 0x%x ", crc);  
}

测试工具:

http://www.ip33.com/crc.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值