CRC-16 0x8005多项式,从C到C#.紧急求救 [英] CRC-16 0x8005 polynominal, from C to C#. SOS

查看:132
本文介绍了CRC-16 0x8005多项式,从C到C#.紧急求救的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这辈子无法理解的C代码块.我需要为发送到该方法的某个字节数组计算CRC-16,它应该给我msb(最高有效字节)和lsb(最低有效字节).我还得到了一个用C语言编写的应用程序,用于测试某些功能,并且该应用程序还为我提供了通过COM端口发送和接收的日志.

I have this block of C code that I can not for the life of me understand. I need to calculate the CRC-16 for a certain byte array I send to the method and it should give me the msb(most significant byte) and the lsb(least significant byte). I was also given a C written app to test some functionality and that app also gives me a log of what is sent and what is received via COM port.

奇怪的是,我将在日志中找到的十六进制字符串输入了

What is weird is that I entered the hex string that I found in the log into this online calculator, but it gives me a different result.

我试图将方法转换为C#,但我不理解某些方面:

I took a stab at translating the method to C#, but I don't understand certain aspects:

  1. 那里的pucPTR在做什么(它在其他任何地方都没有使用过蜂)?
  2. 在第一行中,两行代码是什么意思?
  3. 为什么第二个短字母"i"是< = 7,不应该是< = 8吗?
  4. if语句的最后一行表示usCRC实际上是ushort 8005吗?

这是代码块:

unsigned short CalculateCRC(unsigned char* a_szBufuer, short a_sBufferLen)
{
    unsigned short usCRC = 0;
    for (short j = 0; j < a_sBufferLen; j++)
    {
        unsigned char* pucPtr = (unsigned char*)&usCRC;
        *(pucPtr + 1) = *(pucPtr + 1) ^ *a_szBufuer++;
        for (short i = 0; i <= 7; i++)
        {
            if (usCRC & ((short)0x8000))
            {
                usCRC = usCRC << 1;
                usCRC = usCRC ^ ((ushort)0x8005);
            }
            else
                usCRC = usCRC << 1;
        }
    }
    return (usCRC);
}

这是我转换为字节数组并发送给方法的十六进制字符串:02 00 04 a0 00 01 01 03

This is the hex string that I convert to byte array and send to the method: 02 00 04 a0 00 01 01 03

这是应该从CRC演算中得出的结果:06 35

This is the result that should be given from the CRC calculus: 06 35

我收到的文件说这是整个数据的IBM CRC16(msb,lsb).

The document I have been given says that this is a CRC16 IBM (msb, lsb) of the entire data.

任何人都可以帮忙吗?我已经坚持了一段时间了.

Can anyone please help? I've been stuck on it for a while now.

有没有代码能够将C方法转换为C#?显然我没有这种能力.

Any code guru out there capable of translating that C method to C#? Apparently I'm not capable of such sourcery.

推荐答案

首先,请注意,在C语言中, ^ 运算符意味着按位XOR.

First of all, please note than in C, the ^ operator means bitwise XOR.

  1. 那里的pucPTR是做什么的(在其他任何地方都没有使用beeing)?
  2. 在第一行中,两行代码是什么意思?

从外观上引起错误.它仅用于获取FCS的两个字节之一,但是代码以与字节序有关的方式编写.

Causing bugs, by the looks of it. It is only used to grab one of the two bytes of the FCS, but the code is written in an endianess-dependent way.

在处理校验和算法时,字节序非常重要,因为它们最初是为硬件移位寄存器设计的,该寄存器需要MSB首先,也就是大字节序.另外,CRC通常意味着数据通信,而数据通信意味着发送方,协议和接收方之间的字节序可能不同.

Endianess is very important when dealing with checksum algorithms, since they were originally designed for hardware shift registers, that require MSB first, aka big endian. In addition, CRC often means data communication, and data communication means possibly different endianess between the sender, the protocol and the receiver.

我猜想这段代码只为小端机器编写,目的是与ms字节进行XOR.该代码指向第一个字节,然后使用+1指针算法获得第二个字节.更正后的代码应类似于:

I would guess that this code was written for little endian machines only and the intent is to XOR with the ms byte. The code points to the first byte then uses +1 pointer arithmetic to get to the second byte. Corrected code should be something like:

uint8_t puc = (unsigned int)usCRC >> 8;
puc ^= *a_szBufuer;
usCRC = (usCRC & 0xFF) | ((unsigned int)puc << 8);
a_szBufuer++;

对unsigned int的强制转换可以很好地防止隐式整数升级带来的不幸.

The casts to unsigned int are there to portably prevent mishaps with implicit integer promotion.

  1. 为什么第二个短字母"i"是< = 7,不应该是< = 8吗?

我认为这是正确的,但更可理解的是,它可以写成 i<8 .

I think it is correct, but more readably it could have been written as i < 8.

  1. if语句的最后一行表示usCRC实际上是ushort 8005吗?

否,这意味着要将您的FCS与多项式0x8005异或.参见.

No, it means to XOR your FCS with the polynomial 0x8005. See this.

我收到的文件说这是CRC16 IBM

The document I have been given says that this is a CRC16 IBM

是的,有时被称为.虽然据我所知,"CRC16 IBM"还涉及最终结果的一些反转(?).我会仔细检查.

Yeah it is sometimes called that. Though from what I recall, "CRC16 IBM" also involves some bit inversion of the final result(?). I'd double check that.

总体而言,请谨慎使用此代码.不管是谁写的,都不太了解字节序,整数符号和隐式类型提升.它是业余级别的代码.您应该可以在网上找到更安全,可移植的相同CRC算法的专业版本.

Overall, be careful with this code. Whoever wrote it didn't have much of a clue about endianess, integer signedness and implicit type promotions. It is amateur-level code. You should be able to find safer, portable professional versions of the same CRC algorithm on the net.

关于该主题的非常好阅读是 CRC的无痛指南.

Very good reading about the topic is A Painless Guide To CRC.

这篇关于CRC-16 0x8005多项式,从C到C#.紧急求救的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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