C#中的CRC-CCITT Kermit 16 [英] CRC-CCITT Kermit 16 in C#

查看:376
本文介绍了C#中的CRC-CCITT Kermit 16的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尝试对串行端口协议进行反向工程。我无法重新创建crc-16字节。

Attempting to reverse engineer a serial port protocol. I am unable to recreate the crc-16 bytes.

根据文档,这是数据包的格式

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插槽中为零。 CRC16函数的确返回5C字节,但不返回b1。

I am able to recreate the packet fine, except for the 2 bytes "5c b1". According to the documentation, the 5c b1 bytes is a crc-ccit16 over the packet, with zeros in the crc-16 slot. The CRC16 function does return the 5C byte but not b1.

我正在使用以下代码计算crc:

I am using the code below to calculate the 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();

    }


推荐答案

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

From that one example, it appears to be the X-25 16-bit CRC, not the CCITT (Kermit) 16-bit CRC. There is a 1/65536 chance that this is a coincidence, since there is only one example, so you'd need to try it with several more sniffed packets.

这里是一个简单的一次C例程,它计算CRC(用 mem == NULL 调用返回CRC的初始值):

Here is a simple, bit-at-a-time C routine that calculates that CRC (calling it with mem == NULL returns the initial value for the 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 ,它还为字节码和字码表驱动版本生成代码。

That code was generated by crcany, which also generates code for table-driven versions, both byte-wise and word-wise.

这篇关于C#中的CRC-CCITT Kermit 16的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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