功能用来计算CRC16校验 [英] Function to Calculate a CRC16 Checksum

查看:404
本文介绍了功能用来计算CRC16校验的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在图书馆工作,提供了一个RS232或RS485接口简单可靠的通信。这code部分涉及到使用上的数据CRC16校验检测来自行噪声干扰。我创建了一个函数来计算CRC16校验,但它似乎并没有被输出正确的价值观。

I'm working on a library to provide simple reliable communication over an RS232 or RS485 connection. Part of this code involves using a CRC16 checksum on the data to detect corruption from line noise. I've created a function to calculate a CRC16 checksum, but it doesn't seem to be outputting correct values.

相关code我已经写了,可以发现这里

The relevant code I've written can be found here.

我检查我对这个网上CRC计算器。

我已经得出结论,要么我对如何计算CRC16理解是错误的,或者在线计算器是错误的(前者似乎更可能)。谁能告诉我,我可能会去错了吗?

I've come to the conclusion that either my understanding of how to calculate a CRC16 is wrong, or the online calculator is wrong (the former seems more likely). Can someone tell me where I might be going wrong?

感谢。

推荐答案

有您需要使用匹配特定CRC实现几个细节 - 即使使用的,因为细微的差别同样的多项式可以有不同的结果如何数据位的处理,使用用于CRC(有时是零,有时为0xFFFF)一个特定的初始值,和/或反相CRC的比特。例如,有时一个实现将从低位运行的数据字节了,而有时他们会从高位下来的工作(如你目前还)。

There are several details you need to 'match up' with for a particular CRC implementation - even using the same polynomial there can be different results because of minor differences in how data bits are handled, using a particular initial value for the CRC (sometimes it's zero, sometimes 0xffff), and/or inverting the bits of the CRC. For example, sometimes one implementation will work from the low order bits of the data bytes up, while sometimes they'll work from the high order bits down (as yours currently does).

此外,你需要'推出'CRC的最后一位你已经通过运行所有数据位之后。

Also, you need to 'push out' the last bits of the CRC after you've run all the data bits through.

请记住,CRC算法被设计在硬件中实现,所以一些位顺序是如何处理可能无法从软件的角度来看赚那么多意义。

Keep in mind that CRC algorithms were designed to be implemented in hardware, so some of how bit ordering is handled may not make so much sense from a software point of view.

如果您希望lammertbies.nl CRC计算器页所示,以配合多项式0x8005的CRC16,你需要做以下更改CRC功能:

If you want to match the CRC16 with polynomial 0x8005 as shown on the lammertbies.nl CRC calculator page, you need to make the following changes to your CRC function:


  • 一)通过CRC循环运行数据位从至少显著位,而不是从最显著位
  • 开始
  • 二)推动CRC的最后16位出了CRC的注册你完成输入数据后

  • c)进行反向CRC比特(我猜这一位是从硬件实现结转)

所以,你的函数可能是这样的:

So, your function might look like:

#define CRC16 0x8005

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

    /* 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;
}

在该函数返回 0xbb3d 对我来说,当我通过在123456789

That function returns 0xbb3d for me when I pass in "123456789".

这篇关于功能用来计算CRC16校验的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆