关于 CRC16 计算的说明
Clarification regarding CRC16 calculation
我第一次尝试计算CRC。我已经阅读了几页解释什么是 crc 以及如何计算。主要是这个:https://www.fatalerrors.org/a/implementation-of-crc-checksum-c-crc16-as-an-example.html
我有一个计算 CRC16 的代码
uint16_t CalCrc(uint16_t crc_initial, uint8_t* buf,uint16_t len,uint16_t POLY)
{
unsigned int byte;
unsigned char k;
unsigned short ACC,TOPBIT;
unsigned short remainder = crc_initial;
TOPBIT = 0x8000;
for (byte = 0; byte < len; ++byte)
{
ACC = buf[byte];
remainder ^= ACC;
printf("new remainder = %u \n",remainder);
for (k = 8; k > 0; --k)
{
if (remainder & TOPBIT)
{
remainder = remainder << 1;
remainder = remainder ^ POLY;
}
else
{
remainder = (remainder << 1);
}
}
}
remainder = remainder^0x0000;
printf("result remainder = %02X \n",remainder);
return remainder;
}
我称之为我的 main.c:
uint8_t crc_buf[5] = {0x05,0x03,0x04,0x08,0x04};
CalCrc(0xffff,crc_buf,5,0x1021);
结果是:
result remainder = BDD5
正如您从我的函数调用中看到的那样,我将 0xffff 作为初始 crc 值传递,将 0x1021 作为多项式传递。
我正在尝试使用一些在线 CRC 计算器来确认我的计算是否正确,例如:
http://www.sunshine2k.de/coding/javascript/crc/crc_js.html
https://crccalc.com/
根据我使用的初始值和多项式值,结果应该是:
有人可以帮助我了解这里出了什么问题吗?提前致谢。
您在计算中遗漏了位移位。变化:
ACC = buf[byte];
至:
ACC = (unsigned)buf[byte] << 8;
与 Sunshine Understanding and implementing CRC (Cyclic Redundancy Check) calculation 中的此 C# 示例代码进行比较:
public static ushort Compute_CRC16_Simple(byte[] bytes)
{
const ushort generator = 0x1021; /* divisor is 16bit */
ushort crc = 0; /* CRC value is 16bit */
foreach (byte b in bytes)
{
crc ^= (ushort(b << 8); /* move byte into MSB of 16bit CRC */
for (int i = 0; i < 8; i++)
{
if ((crc & 0x8000) != 0) /* test for MSB = bit 15 */
{
crc = (ushort((crc << 1) ^ generator);
}
else
{
crc <<= 1;
}
}
}
return crc;
}
它使用与您的函数不同的初始值,但请注意将字节异或到 16 位 CRC 的 MSB 的行:
crc ^= (ushort(b << 8); /* move byte into MSB of 16bit CRC */
我第一次尝试计算CRC。我已经阅读了几页解释什么是 crc 以及如何计算。主要是这个:https://www.fatalerrors.org/a/implementation-of-crc-checksum-c-crc16-as-an-example.html
我有一个计算 CRC16 的代码
uint16_t CalCrc(uint16_t crc_initial, uint8_t* buf,uint16_t len,uint16_t POLY)
{
unsigned int byte;
unsigned char k;
unsigned short ACC,TOPBIT;
unsigned short remainder = crc_initial;
TOPBIT = 0x8000;
for (byte = 0; byte < len; ++byte)
{
ACC = buf[byte];
remainder ^= ACC;
printf("new remainder = %u \n",remainder);
for (k = 8; k > 0; --k)
{
if (remainder & TOPBIT)
{
remainder = remainder << 1;
remainder = remainder ^ POLY;
}
else
{
remainder = (remainder << 1);
}
}
}
remainder = remainder^0x0000;
printf("result remainder = %02X \n",remainder);
return remainder;
}
我称之为我的 main.c:
uint8_t crc_buf[5] = {0x05,0x03,0x04,0x08,0x04};
CalCrc(0xffff,crc_buf,5,0x1021);
结果是:
result remainder = BDD5
正如您从我的函数调用中看到的那样,我将 0xffff 作为初始 crc 值传递,将 0x1021 作为多项式传递。
我正在尝试使用一些在线 CRC 计算器来确认我的计算是否正确,例如: http://www.sunshine2k.de/coding/javascript/crc/crc_js.html https://crccalc.com/
根据我使用的初始值和多项式值,结果应该是:
有人可以帮助我了解这里出了什么问题吗?提前致谢。
您在计算中遗漏了位移位。变化:
ACC = buf[byte];
至:
ACC = (unsigned)buf[byte] << 8;
与 Sunshine Understanding and implementing CRC (Cyclic Redundancy Check) calculation 中的此 C# 示例代码进行比较:
public static ushort Compute_CRC16_Simple(byte[] bytes)
{
const ushort generator = 0x1021; /* divisor is 16bit */
ushort crc = 0; /* CRC value is 16bit */
foreach (byte b in bytes)
{
crc ^= (ushort(b << 8); /* move byte into MSB of 16bit CRC */
for (int i = 0; i < 8; i++)
{
if ((crc & 0x8000) != 0) /* test for MSB = bit 15 */
{
crc = (ushort((crc << 1) ^ generator);
}
else
{
crc <<= 1;
}
}
}
return crc;
}
它使用与您的函数不同的初始值,但请注意将字节异或到 16 位 CRC 的 MSB 的行:
crc ^= (ushort(b << 8); /* move byte into MSB of 16bit CRC */