2016-08-23 21 views
0

Modbus RTUのCRC計算機能をC#からPythonに移植しようとしています。私はこのように実行ポートModbus RTU CRC to Python to C#

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です。

実際に、C#のようにCRCが0xCAD5であることがわかっています。

私は両方の例では、ステップバイステップでデバッグする場合、変数「CRCは」これらのコード行の後に差分値を持っています

crc ^= (UInt16)data[pos]; 

VS

crc ^= pos 

私は何をしないのですか?

/Mc_Topaz

答えて

1

あなたの内側のループではなく、固定された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))