从 C# 端口 Modbus RTU CRC 到 python

Port Modbus RTU CRC to python from C#

我正在尝试将 Modbus RTU 的 CRC 计算函数从 C# 移植到 Python。

C#

private static ushort CRC(byte[] data)
{
    ushort crc = 0xFFFF;
    for (int pos = 0; pos < data.Length; pos++)
    {
        crc ^= (UInt16)data[pos];
        for (int i = 8; i != 0; i--)
        {
           if ((crc & 0x0001) != 0)
           {
               crc >>= 1;
               crc ^= 0xA001;
           }
           else
           {
               crc >>= 1;
           }
       }
    }
    return crc;
}

我运行喜欢这样:

byte[] array = { 0x01, 0x03, 0x00, 0x01, 0x00, 0x01 };
ushort u = CRC(array);
Console.WriteLine(u.ToString("X4"));

Python

def CalculateCRC(data):
    crc = 0xFFFF
    for pos in data:
        crc ^= pos
        for i in range(len(data)-1, -1, -1):
            if ((crc & 0x0001) != 0):
                crc >>= 1
                crc ^= 0xA001
            else:
                crc >>= 1
    return crc

我运行喜欢这样:

data = bytearray.fromhex("010300010001")
crc = CalculateCRC(data)
print("%04X"%(crc))

我从其他应用程序中得知 CRC 应该是 0xCAD5,正如 C# 示例所提供的那样。

当我逐步调试这两个示例时,变量 'crc' 在这些代码行之后具有不同的值:

crc ^= (UInt16)data[pos];

VS

crc ^= pos

我错过了什么?

/Mc_Topaz

您的内部循环使用数据数组的大小而不是固定的 8 次迭代。试试这个:

def calc_crc(data):
    crc = 0xFFFF
    for pos in data:
        crc ^= pos 
        for i in range(8):
            if ((crc & 1) != 0):
                crc >>= 1
                crc ^= 0xA001
            else:
                crc >>= 1
    return crc

data = bytearray.fromhex("010300010001")
crc = calc_crc(data)
print("%04X"%(crc))