C#中的CRC-CCITT 16位计算

时间:2019-06-20 03:15:47

标签: 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是数据

10-DLE

03 -ETX

B4-CRC下拜

5C-CRC-上拜

CCIT : (Fx) = x16 + x12 + x5 + 1

操作初始值:FFFFH

我尝试了一些在线CRC计算器,但到目前为止还算不上运气,有人可以指导如何为上述数据(B1 F0 3F 32 08 00 00)计算CRC吗?可能可以建议在线计算器,它可以为我提供以上的输出(B4 5C)

感谢您的指教!

2 个答案:

答案 0 :(得分:1)

我发现了一些可行的方法,但似乎有些奇怪。

首先我将两个样本进行了异或

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,然后单击“自定义”并将参数设置为:输入反射选中,输出反射选中,poly = 0x1021。没有足够的信息来确定初始值和最终异或值,而没有不同大小的消息。使用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值。

http://www.sunshine2k.de/coding/javascript/crc/crc_js.html

答案 1 :(得分:0)

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

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

原始链接:http://sanity-free.org/133/crc_16_ccitt_in_csharp.html