微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

CRC-16 输出消息校验

如何解决CRC-16 输出消息校验

我有一个使用 CRC-16 计算字符 CRC 的程序。程序如下。

#include<stdio.h>
#include<stdint.h>

#define CRC16 0x8005

uint16_t gen_crc16(const uint8_t *data,uint16_t size)
{
uint16_t out = 0;
int bits_read = 0,bit_flag;


// test
printf("buffer in function %s\n",data);

/* Sanity check: */
if(data == NULL)
    return 0;

while(size > 0)
{
    bit_flag = out >> 15;

    /* Get next bit: */
    out <<= 1;
    out |= (*data >> bits_read) & 1; // item a) work from the least significant bits

    /* Increment bit counter: */
    bits_read++;
    if(bits_read > 7)
    {
        bits_read = 0;
        data++;
        size--;
    }

    /* Cycle check: */
    if(bit_flag)
        out ^= CRC16;

}

// item b) "push out" the last 16 bits
int i;
for (i = 0; i < 16; ++i) {
    bit_flag = out >> 15;
    out <<= 1;
    if(bit_flag)
        out ^= CRC16;
}

// item c) reverse the bits
uint16_t crc = 0;
i = 0x8000;
int j = 0x0001;
for (; i != 0; i >>=1,j <<= 1) {
    if (i & out) crc |= j;
}

return crc;
}

int main()
{
char buf[]="123456789";
int c,r;
printf ("the buf has %s",buf);
r = gen_crc16(buf,sizeof(buf)-1);
printf("%04hx\n",r);

return (0);
}

问题: 我试图以这样的方式修改代码,我可以在输入数据的末尾附加返回的 CRC 值并再次调用函数 gen_crc()。 gen_crc() 函数这次应该返回 0。

直到现在还不能实现任何帮助或建议是非常受欢迎的。我是初学者

The above C program is taken as a reference from the earlier StackOverflow post

解决方法

代码只需要声明 buf[11] 以便有空间附加 CRC,然后附加 CRC。其他一些是为与 Visual Studio 一起使用而进行的更改(用于局部变量的缩进块)。 CRC计算可以简化。

#include<stdio.h>
#include<stdint.h>

#define CRC16 0x8005

uint16_t gen_crc16(const uint8_t *data,uint16_t size)
{
uint16_t out = 0;
int bits_read = 0,bit_flag;


    /* test */
    printf("buffer in function %s\n",data);

    /* Sanity check: */
    if(data == NULL)
        return 0;

    while(size > 0)
    {
        bit_flag = out >> 15;
    
        /* Get next bit: */
        out <<= 1;
        out |= (*data >> bits_read) & 1; /* item a) work from the least significant bits */
    
        /* Increment bit counter: */
        bits_read++;
        if(bits_read > 7)
        {
            bits_read = 0;
            data++;
            size--;
        }
    
        /* Cycle check: */
        if(bit_flag)
            out ^= CRC16;
    
    }

    /* Cycle check: */
    if(bit_flag)
        out ^= CRC16;

    }

                                        /* item b) "push out" the last 16 bits */
    {                                   /* block used for local variables */
    int i;
        for (i = 0; i < 16; ++i) {
            bit_flag = out >> 15;
            out <<= 1;
        if(bit_flag)
            out ^= CRC16;
        }
    }

                                        /* item c) reverse the bits */
    {                                   /* block used for local variables */
    uint16_t crc = 0;
    int i;
    i = 0x8000;
    int j = 0x0001;
        for (; i != 0; i >>=1,j <<= 1) {
            if (i & out) crc |= j;
        }
        return crc;
    }
}

int main()
{
char buf[11]="123456789";               /* leave room for crc */
int r;
    printf ("the buf has %s",buf);
    r = gen_crc16(buf,9);              /* 9 data bytes */
    printf("%04hx\n",r);
    buf[ 9] = (char)((r>>0)&0xff);      /* append crc to data */
    buf[10] = (char)((r>>8)&0xff);
    r = gen_crc16(buf,11);             /* 9 data bytes + 2 crc bytes */
    printf("%04hx\n",r);
    return (0);
}

计算完全相同的 CRC 的简化版本:

#define CRC16 0xa001

uint16_t gen_crc16(const uint8_t *data,uint16_t size)
{
uint16_t crc = 0;
int i;
    while(size--){
        crc ^= *data++;
        for(i = 0; i < 8; i++)
            crc = (crc&1) ? (crc>>1)^CRC16 : (crc>>1);
    }
    return crc;         
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。