首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >CRC-CCITT Kermit 16在C#中的应用

CRC-CCITT Kermit 16在C#中的应用
EN

Stack Overflow用户
提问于 2017-01-10 02:46:37
回答 1查看 1.3K关注 0票数 1

试图反向工程一个串口协议。我无法重新创建crc-16字节。

根据文档,这是包的格式

代码语言:javascript
复制
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

这是从串行监视中嗅探出来的写命令

代码语言:javascript
复制
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   

除了两个字节"5c b1“外,我还可以重新创建数据包。根据文档,5c b1字节是数据包上的crc-ccit16 16,crc-16插槽中为零。CRC16函数确实返回5C字节,但不返回b1。

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

代码语言:javascript
复制
  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();

    }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-01-10 18:13:40

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

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

代码语言:javascript
复制
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;
}

该代码是由克拉卡尼生成的,它还为表驱动的版本生成代码,无论是字节驱动版本还是字驱动版本。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41560322

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档