C# C语言中的CRC-CCITT 16位计算

C# C语言中的CRC-CCITT 16位计算,c#,checksum,crc,C#,Checksum,Crc,我正在尝试写一个串口通信程序,在这里我需要发送数据包和CRC,我正在用C语言写这段代码 下面是接收端希望使用CRC的示例数据包 10 02 B1 F0 3F 32 08 00 00 10 03 B4 5C 第二个数据包:10 02 B1 F0 3F 32 07 00 00 10 03 4D EE 10-DLE代码 02-STX B1 F0 3F 32 08 00 00是数据 十点 03-ETX B4-CRC下通道 5C-CRC-上电路 CCIT : (Fx) = x16 + x12 + x5

我正在尝试写一个串口通信程序,在这里我需要发送数据包和CRC,我正在用C语言写这段代码

下面是接收端希望使用CRC的示例数据包

10 02 B1 F0 3F 32 08 00 00 10 03 B4 5C
第二个数据包:10 02 B1 F0 3F 32 07 00 00 10 03 4D EE

10-DLE代码

02-STX

B1 F0 3F 32 08 00 00是数据

十点

03-ETX

B4-CRC下通道

5C-CRC-上电路

CCIT : (Fx) = x16 + x12 + x5 + 1
操作初始值:FFFFH

我试过一些在线CRC计算器,但到目前为止运气不好,有人能指导如何计算上述数据的CRC 1 F0 3F 32 08 00吗?可能是可以建议在线计算器,可以给我以上的输出B4 5C


谢谢你的建议

我发现了一些有效的方法,但似乎有点奇怪

首先我对两个样本进行了异或运算

10 02 B1 F0 3F 32 08 00 00 10 03 B4 5C
10 02 B1 F0 3F 32 07 00 00 10 03 4D EE
--------------------------------------
00 00 00 00 00 00 0F 00 00 00 00 F9 B2
这消除了初始CRC和最终xor值,并导致使用位反射0x11021 CRC。CRC似乎使用了8个字节的数据,包括尾随的0x10

使用下面链接的CRC计算器,选择任意CRC16,然后单击“自定义”并将参数设置为:输入反射检查,输出反射检查,多边形=0x1021。如果没有不同大小的消息,则没有足够的信息来确定初始值和最终xor值。使用8字节的数据,一些示例选项是:初始值=0x5B08,最终异或值=0x0000,或初始值=0xffff,最终异或值=0xdde5,或初始值=0x0000,最终异或值=0xa169

使用反射参数时,计算器位反转初始值0x5B08为0x17DA位反转。对于代码,3个组合是{0x17da,0x0000},0xffff,0xdde5},{0x0000,0xa169}。Poly=0x8408,并右移

用xx表示输入的数据,我得到

xx xx B1 F0 3F 32 08 00 00 10 xx B4 5C
xx xx B1 F0 3F 32 07 00 00 10 xx 4D EE
由于前两个字节是{10 02},是固定值,因此可以通过更改初始值来包含它们。但是,我无法包含ETX 03的值


我在网上找到了第二个热门网站,但我将其内容复制到此处以供参考:

using System;

public enum InitialCrcValue { Zeros, NonZero1 = 0xffff, NonZero2 = 0x1D0F }

public class Crc16Ccitt {
    const ushort poly = 4129;
    ushort[] table = new ushort[256];
    ushort initialValue = 0;

    public ushort ComputeChecksum(byte[] bytes) {
        ushort crc = this.initialValue;
        for(int i = 0; i < bytes.Length; ++i) {
            crc = (ushort)((crc << 8) ^ table[((crc >> 8) ^ (0xff & bytes[i]))]);
        }
        return crc;
    }

    public byte[] ComputeChecksumBytes(byte[] bytes) {
        ushort crc = ComputeChecksum(bytes);
        return BitConverter.GetBytes(crc);
    }

    public Crc16Ccitt(InitialCrcValue initialValue) {
        this.initialValue = (ushort)initialValue;
        ushort temp, a;
        for(int i = 0; i < table.Length; ++i) {
            temp = 0;
            a = (ushort)(i << 8);
            for(int j = 0; j < 8; ++j) {
                if(((temp ^ a) & 0x8000) != 0) {
                    temp = (ushort)((temp << 1) ^ poly);
                } else {
                    temp <<= 1;
                }
                a <<= 1;
            }
            table[i] = temp;
        }
    }
}

原始链接:

这并不明显,我建议阅读手册以确定什么是crc'd是否仅是数据,是否是整个数据包,这似乎没有任何意义。感谢您的回复,只有数据部分需要包含在crc中,即B1 F0 3F 32 08 00 00这里缺少一些内容,这似乎不是CRC16SIT众多类型中的一种,如果你能得到与第一个数据包差别不大的第二个样本数据包,那么一个字节的差别会有所帮助。然后,您可以对第一个和第二个样本进行异或运算,以获得大部分为零的数据。感谢您的详细回答,link将根据顺序数据尝试不同的选项。