为了账号安全,请及时绑定邮箱和手机立即绑定

不同的 crc16 C 和 Python3?

不同的 crc16 C 和 Python3?

素胚勾勒不出你 2022-06-28 17:56:46
我有两个 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
查看完整描述

2 回答

?
慕森卡

TA贡献1806条经验 获得超8个赞

还有不止一个 CRC-16。22 编目在http://reveng.sourceforge.net/crc-catalogue/16.htm。CRC 的特征在于其宽度、多项式、初始状态以及输入和输出位顺序。


通过将相同的数据应用于您的每个函数:


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 读取位,并且整个 CRC 在输出时不反转。


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


查看完整回答
反对 回复 2022-06-28
?
慕神8447489

TA贡献1780条经验 获得超1个赞

我基于python crc16 lib在C中实现了一个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 值始终匹配,除非出现某些连接问题。希望这对某人有帮助!


查看完整回答
反对 回复 2022-06-28
  • 2 回答
  • 0 关注
  • 258 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信