c# - 将 Modbus RTU CRC 从 C# 移植到 python

标签 c# python crc modbus

我正在尝试将 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))
  • C# 示例的结果是:0xCAD5。
  • Python 示例的结果是:0x8682。

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

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

crc ^= (UInt16)data[pos];

VS

crc ^= pos

我错过了什么?

/麦黄 Jade

最佳答案

您的内部循环使用数据数组的大小,而不是固定的 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))

关于c# - 将 Modbus RTU CRC 从 C# 移植到 python,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39101926/

相关文章:

c# - 基本的 CRC32 维基百科实现与在线看到的标准 CRC32 不同

c# - DataFormatString 格式百分比错误

python - Heroku 'DATABASES' 未定义

c# - DataTemplate内部的 Prism 区域

python - "Element click intercepted"尝试单击复选框时出错

python - 按 'Date' 分组,同时计算其他列的平均值

c++ - POSIX cksum 和 Boost.CRC

一个符号校验和的算法

c# - 为什么我运行的 WebClient.DownloadFileAsync 不能超过 5 个?

c# - 如何修复错误 "Named Pipes Provider, error: 40 - Could not open a connection to SQL Server"