CRC比较和相似算法之间的差异

CRC比较和相似算法之间的差异,c,algorithm,crc16,C,Algorithm,Crc16,我在读有关CRC的文章时,偶然发现了和这篇文章 我基于第二个链接实现了MyCrc16(代码见下文) 它只是将字节,按顺序,按相反顺序,将它们一个接一个地移位到(初始)CRC中,然后与多项式进行异或运算,得到余数,最后加上增广运算 现在。。。我还有一些预先存在的CRC16实现(OtherCrc16),根据目录,它是CRC-16/CCITT-FALSE 我不明白的是,OtherCrc16为什么工作?因为输入的第一个字节以及之后的所有剩余字节都与(初始)CRC进行异或运算,而不像其他实现那样附加到CR

我在读有关CRC的文章时,偶然发现了和这篇文章

我基于第二个链接实现了MyCrc16(代码见下文)

它只是将字节,按顺序,按相反顺序,将它们一个接一个地移位到(初始)CRC中,然后与多项式进行异或运算,得到余数,最后加上增广运算

现在。。。我还有一些预先存在的CRC16实现(
OtherCrc16
),根据目录,它是CRC-16/CCITT-FALSE

我不明白的是,
OtherCrc16
为什么工作?因为输入的第一个字节以及之后的所有剩余字节都与(初始)CRC进行异或运算,而不像其他实现那样附加到CRC上。当它在比特上迭代时,它没有考虑第一个算法所考虑的“将输入移到CRC中”,而是在必要时与多项式进行异或运算

我是否缺少XOR操作的某些属性? 在我看来,这两个算法应该有相同的输出(当然不考虑第一个算法的扩充),但它们没有

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

uint16_t MyCrc16(const unsigned char *data, int length, uint16_t poly, uint16_t crc)
{
        for(int byte=0; byte<length; ++byte)
        {
                for(int bit=7; bit>=0; --bit)
                {
                        bool doXor = false;
                        if(crc & 0x8000)
                        {
                                doXor = true;
                        }
                        crc <<= 1;
                        if(data[byte] & (1 << bit))
                        {
                                crc += 1;
                        }
                        if(doXor)
                        {
                                crc ^= poly;
                        }
                }
        }

        //augument the crc with 0s
        for(int i=0; i<16; i++)
        {
                bool doXor = false;
                if(crc & 0x8000)
                {
                        doXor = true;
                }

                crc = crc << 1;
                if(doXor)
                {
                        crc ^= poly;
                }
        }

        return crc;
}

uint16_t OtherCrc16(const unsigned char *data, int length, uint16_t poly, uint16_t crc)
{
        for(int i=0; i<length; i++)
        {
                crc = crc ^ (data[i] << 8);
                for (int bit = 0; bit< 8; bit++)
                {
                        bool doXor = false;
                        if(crc & 0x8000)
                        {
                                doXor = true;
                        }
                        crc <<=1;

                        if(doXor)
                        {
                                crc ^= poly;
                        }
                }
        }
        return crc;
}


int main(void) {
    // your code goes here
    uint16_t poly = 0x1021;

    unsigned char c[] = "123456789";
    printf("My CRC = %04x\n", MyCrc16(c, 9, poly, 0xffff));
    printf("Other CRC = %04x\n", OtherCrc16(c, 9, poly, 0xffff));
    return 0;
}
#包括
#包括
#包括
uint16\u t MyCrc16(常量无符号字符*数据,整数长度,uint16\u t多边形,uint16\u t crc)
{
for(int字节=0;字节=0;--位)
{
bool-doXor=false;
如果(crc&0x8000)
{
doXor=true;
}

crc如果crc的初始值为零,则两种方法产生相同的crc。但是,如果crc的初始值为非零,则MyCrc16在开始之前将该初始值循环16次,包括任何数据位,就好像它在数据前加了16个零位。对于非零初始crc,MyCrc16需要将初始值反转cled 16次,因此在将初始值向前循环16次后,它与其他CRC16中使用的初始值相同。对于初始值0xffff,反向循环16次将产生0x84cf。注释中注意到的以下更改将导致两种方法产生相同的CRC:

    printf("My CRC = %04x\n", MyCrc16(c, 9, poly, 0x84cf));  /* change to 0x84cf */
    printf("Other CRC = %04x\n", OtherCrc16(c, 9, poly, 0xffff));

阅读。我读过了,我仍然看不出为什么先将消息XORing到CRC中时它会不同……你的意思是,你仍然看不出为什么它是一样的。这在CRC教程中的“10.一个稍微有点混乱的表驱动实现”中得到了非常详细的解释。@MarkAdler-如果初始CRC值不是0x0000,它就不同了。