不同的 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 的特征在于其宽度、多项式、初始状态以及输入和输出位顺序。
通过将相同的数据应用于您的每个函数:
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 以及许多其他。
我在C中基于python crc16 lib实现了一个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 值始终匹配,除非出现某些连接问题。希望这对某人有所帮助!
我有两个 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 的特征在于其宽度、多项式、初始状态以及输入和输出位顺序。
通过将相同的数据应用于您的每个函数:
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 以及许多其他。
我在C中基于python crc16 lib实现了一个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 值始终匹配,除非出现某些连接问题。希望这对某人有所帮助!