簡體   English   中英

不同的 crc16 C 和 Python3?

[英]different crc16 C and Python3?

我有兩個 crc16 計算器(在 C 和 Python 中)。 但我收到不同的結果。 為什么?

C 中的計算器:

unsigned short __update_crc16 (unsigned char data, unsigned short crc16)
{
  unsigned short t;
  crc16 ^= data;
  t = (crc16 ^ (crc16 << 4)) & 0x00ff;
  crc16 = (crc16 >> 8) ^ (t << 8) ^ (t << 3) ^ (t >> 4);
  return crc16;
}


unsigned short get_crc16 (void *src, unsigned int size, unsigned short start_crc)
{
  unsigned short crc16;
  unsigned char *p;
  crc16 = start_crc;
  p = (unsigned char *) src;
  while (size--)
    crc16 = __update_crc16 (*p++, crc16);
  return crc16;
}

Python3中的計算器:

def crc16(data):
    crc = 0xFFFF
    for i in data:
        crc ^= i << 8
        for j in range(0,8):
            if (crc & 0x8000) > 0:
                crc =(crc << 1) ^ 0x1021
            else:
                crc = crc << 1
    return crc & 0xFFFF

還有不止一個 CRC-16。 22 編目在http://reveng.sourceforge.net/crc-catalogue/16.htm CRC 的特征在於其寬度、多項式、初始 state 以及輸入和 output 位順序。

通過將相同的數據應用於您的每個函數:

Python:

data = bytes([0x01, 0x23, 0x45, 0x67, 0x89])
print ( hex(crc16(data)) )

結果: 0x738E

C:

char data[] = {0x01, 0x23, 0x45, 0x67, 0x89};
printf ("%4X\n", get_crc16 (data, sizeof (data), 0xffffu));

結果: 0x9F0D

並將相同的數據應用於生成多個 CRC 的在線工具,例如https://crccalc.com/ ,您可以從結果中識別 CRC。

在這種情況下,您的 Python 代碼是CRC-16-CCITT-FALSE ,而 C 結果匹配CRC-16/MCRF4XX 它們都具有相同的多項式,但輸入反射和輸出反射參數不同(CCITT 為假,MCRF4XX 為真)。 這意味着對於 MCRF4XX,首先從 LSB 讀取位,並且在 output 上將整個 CRC 反轉。

https://pypi.org/project/crccheck/支持 CCITT 和 MCRF4XX 以及許多其他。

我基於python crc16 libC中實現了一個crc16版本。 這個庫計算CRC16 的 CRC-CCITT (XModem) 變體 我在 stm32l4 固件中使用了我的實現。 這是我的 C 實現:

unsigned short _crc16(char *data_p, unsigned short length){
  unsigned int crc = 0;
  unsigned char i;

  for(i = 0; i < length; i++){
     crc = ((crc<<8)&0xff00) ^ CRC16_XMODEM_TABLE[((crc>>8)&0xff)^data_p[i]];
  }

  return crc & 0xffff;

}

Python 端,我正在讀取 stm32 傳輸的 18 個字節。 這是我的一些代碼( crc 的部分):

import crc16

# read first time
crc_buffer  = b''
bytes = serial_comunication.read(2) # int_16 - 2 bytes
crc_buffer = crc_buffer.join([crc_buffer,bytes])
crc = crc16.crc16xmodem(crc_buffer,0)

while aux < 8:
  crc_buffer  = b''
  bytes = serial_comunication.read(2)
  crc_buffer = crc_buffer.join([crc_buffer,bytes])
  crc = crc16.crc16xmodem(crc_buffer,crc)

print(crc)

在我的測試中,C 和 Python crc16 值始終匹配,除非出現某些連接問題。 希望這對某人有幫助!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM