当前位置: 首页 > 知识库问答 >
问题:

C#中的CRC-CCITT Kermit 16

长孙绍辉
2023-03-14
48 45 4c 4f // HELO
01 00 00 01 // ARG 1
00 00 00 00 // ARG 2
00 00 00 00 // ARG 3
00 00 00 00 // ARG 4
00 00 00 00 // REQUEST BODY
5c b1 00 00 // CRC-16
b7 ba b3 b0  // Bit-wise inversion of HELO command
48 45 4c 4f 01 00 00 01 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 5c b1 00 00 b7 ba b3 b0   

我能够重新创建包罚款,除了2字节“5C B1”。根据文档,5C b1字节是数据包上的crc-ccit16,在crc-16时隙中有0。CRC16函数返回5c字节,但不返回b1字节。

我使用下面的代码来计算CRC:

  public class Crc16
{
    static ushort[] table = new ushort[256];

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

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

    public Crc16(Crc16Mode mode)
    {
        ushort polynomial = (ushort)mode;
        ushort value;
        ushort temp;
        for (ushort i = 0; i < table.Length; ++i)
        {
            value = 0;
            temp = i;
            for (byte j = 0; j < 8; ++j)
            {
                if (((value ^ temp) & 0x0001) != 0)
                {
                    value = (ushort)((value >> 1) ^ polynomial);
                }
                else {
                    value >>= 1;
                }
                temp >>= 1;
            }
            table[i] = value;
        }
    }
}

       public byte[] getPreCRC16Bytes()
    {
            byte[] x = new byte[28];
            byte[] cmdBytes = Encoding.ASCII.GetBytes(this.cmd.ToString());
            byte[] arg1Bytes = (byte[])this.arg1;
            byte[] arg2Bytes = (byte[])this.arg2;
            byte[] arg3Bytes = (byte[])this.arg3;
            byte[] arg4Bytes = (byte[])this.arg4;
            byte[] bodyLen = { 0x00, 0x00, 0x00, 0x00 };
            byte[] emptyCRC = { 0x00, 0x00, 0x00, 0x00 };
            byte[] checksum = Encoding.ASCII.GetBytes(this.checksum);
            var list = new List<byte>();
            list.AddRange(cmdBytes);
            list.AddRange(arg1Bytes);
            list.AddRange(arg2Bytes);
            list.AddRange(arg3Bytes);
            list.AddRange(arg4Bytes);
            list.AddRange(bodyLen);
            list.AddRange(emptyCRC);
            list.AddRange(checksum);
            var xx = list.ToArray();

        string hex = BitConverter.ToString(cmdBytes).Replace("-", "");

        return list.ToArray();

    }

共有1个答案

鲁峰
2023-03-14

从这个例子来看,它似乎是X-25 16位CRC,而不是CCITT(Kermit)16位CRC。有1/65536的机会这是一个巧合,因为只有一个例子,所以您需要尝试几个更多的嗅探包。

下面是一个简单的、一次一位的C例程,它计算CRC(用mem==null调用它,返回CRC的初始值):

unsigned crc16x_25_bit(unsigned crc, void const *mem, size_t len) {
    unsigned char const *data = mem;
    if (data == NULL)
        return 0;
    crc = ~crc;
    crc &= 0xffff;
    while (len--) {
        crc ^= *data++;
        for (unsigned k = 0; k < 8; k++)
            crc = crc & 1 ? (crc >> 1) ^ 0x8408 : crc >> 1;
    }
    crc ^= 0xffff;
    return crc;
}

该代码是由crcany生成的,crcany还为表驱动版本生成代码,包括字节和字。

 类似资料:
  • 在C语言中也有一个类似的问题被问到和回答,但我在C#中遇到了一些困难。 我有48位数据,现在我需要生成16位CRC,下面是代码: 但是上面的代码,给了我错误的输出,请建议我如果有什么更好的方法做它。

  • 我有一个通过RS232 COM与计算机通信的终端。我得到的协议说,我必须发送一定的字节组合和CRC 16 IBM计算的数据在最后发送 我还得到了一个C编写的应用程序,我可以用它来测试,该应用程序编写了一个带有发送数据和接收数据的日志。在该日志中,我查看是否向终端发送了以下字符串。我还必须发送数据06 35的这个CRC16 IBM结果。 我已经设法以某种方式将作为示例给出的C方法翻译成C#。但我的结

  • 我目前正在建立步进电机控制器和计算机之间的通信,用C#编写一个应用程序(这是我第一次使用这种编程语言,虽然我不是计算机科学家,而是工业工程师,但我肯定有一些优化功能的方法,我不知道,关于这一点的任何建议也将非常感谢)。因此,我一直使用控制器必须与其通信的RS-485,并实现了一个生成所需CRC(循环冗余校验)字节的算法。 使用附加的测试数组和多项式0xA001的预期结果对于CRC_Register

  • http://www.lammertbies.nl/comm/info/crc-calculation.html http://www.codeproject.com/articles/19059/c-ccitt-crc-algorithm 在上面与字节数组{0xee,0x01,0x13,0x00,0x06,0x1c,0x00,0x20,0x1d,0x00,0x00}的链接中,它使用CRC8(po

  • 为了避免多次重新计算一个项目的数据,我希望对这些项目使用已经计算好的crc。或以伪代码: 问题是combine_magic应该是什么。我使用boost crc库,但我没有在那里找到这样的功能。简单地使用xor是一个坏主意,因为我可能会完成一些指向偶数次的项--这将从等式中消除它们。Zlib似乎提供了这样的函数https://github.com/madler/Zlib/blob/master/cr

  • 我有两个来源来计算看似相同的crc值。我不明白为什么'boost/crc.hpp'实现与'linux/lib/crc-ccitt.c'实现不同。 CRC-CCITT.C boost 这里有一个例子说明了这个问题。因为我的电脑上没有Linux内核源码,所以这是一个很长的时间。如果将boost链接到它,它就会编译。 null 我的机器上的输出是: