我尝试在C++中为已知的CRC算法 CRC-4 / INTERLAKEN 和 CRC-4 / ITU 生成CRC4查找表。 CRC定义如下:
width=4 poly=0x3 init=0xf refin=false refout=false xorout=0xf check=0xb residue=0x2 name="CRC-4/INTERLAKEN"
width=4 poly=0x3 init=0x0 refin=true refout=true xorout=0x0 check=0x7 residue=0x0 name="CRC-4/G-704"
我已经开始调整从answer here中找到的代码来生成查找表,以与在answer found here中找到的表进行比较。如果该代码的位顺序无关紧要,除了多项式相同,我还需要考虑什么? INTERLAKEN和ITU算法的代码有何不同?
编码:
#include <iomanip>
#include <iostream>
void make_crc_table(unsigned long crcTable[])
{
unsigned long POLYNOMIAL = 0x3;
unsigned long remainder;
unsigned char b = 0;
do
{
remainder = b;
for (unsigned long bit = 8; bit > 0; --bit)
{
if (remainder & 1)
remainder = (remainder >> 1) ^ POLYNOMIAL;
else
remainder = (remainder >> 1);
}
crcTable[(size_t)b] = remainder;
} while (0 != ++b);
}
int main()
{
unsigned long crcTable[256];
make_crc_table(crcTable);
// Print the CRC table
for (size_t i = 0; i < 256; i++)
{
std::cout << "0x";
std::cout << std::setfill('0') << std::setw(2) << std::hex << crcTable[i];
if (i % 16 == 15)
std::cout << "," << std::endl;
else
std::cout << ", ";
}
return 0;
}
输出:
0x00, 0x02, 0x03, 0x01, 0x01, 0x03, 0x02, 0x00, 0x02, 0x00, 0x01, 0x03, 0x03, 0x01, 0x00, 0x02,
0x03, 0x01, 0x00, 0x02, 0x02, 0x00, 0x01, 0x03, 0x01, 0x03, 0x02, 0x00, 0x00, 0x02, 0x03, 0x01,
0x01, 0x03, 0x02, 0x00, 0x00, 0x02, 0x03, 0x01, 0x03, 0x01, 0x00, 0x02, 0x02, 0x00, 0x01, 0x03,
0x02, 0x00, 0x01, 0x03, 0x03, 0x01, 0x00, 0x02, 0x00, 0x02, 0x03, 0x01, 0x01, 0x03, 0x02, 0x00,
0x02, 0x00, 0x01, 0x03, 0x03, 0x01, 0x00, 0x02, 0x00, 0x02, 0x03, 0x01, 0x01, 0x03, 0x02, 0x00,
0x01, 0x03, 0x02, 0x00, 0x00, 0x02, 0x03, 0x01, 0x03, 0x01, 0x00, 0x02, 0x02, 0x00, 0x01, 0x03,
0x03, 0x01, 0x00, 0x02, 0x02, 0x00, 0x01, 0x03, 0x01, 0x03, 0x02, 0x00, 0x00, 0x02, 0x03, 0x01,
0x00, 0x02, 0x03, 0x01, 0x01, 0x03, 0x02, 0x00, 0x02, 0x00, 0x01, 0x03, 0x03, 0x01, 0x00, 0x02,
0x03, 0x01, 0x00, 0x02, 0x02, 0x00, 0x01, 0x03, 0x01, 0x03, 0x02, 0x00, 0x00, 0x02, 0x03, 0x01,
0x00, 0x02, 0x03, 0x01, 0x01, 0x03, 0x02, 0x00, 0x02, 0x00, 0x01, 0x03, 0x03, 0x01, 0x00, 0x02,
0x02, 0x00, 0x01, 0x03, 0x03, 0x01, 0x00, 0x02, 0x00, 0x02, 0x03, 0x01, 0x01, 0x03, 0x02, 0x00,
0x01, 0x03, 0x02, 0x00, 0x00, 0x02, 0x03, 0x01, 0x03, 0x01, 0x00, 0x02, 0x02, 0x00, 0x01, 0x03,
0x01, 0x03, 0x02, 0x00, 0x00, 0x02, 0x03, 0x01, 0x03, 0x01, 0x00, 0x02, 0x02, 0x00, 0x01, 0x03,
0x02, 0x00, 0x01, 0x03, 0x03, 0x01, 0x00, 0x02, 0x00, 0x02, 0x03, 0x01, 0x01, 0x03, 0x02, 0x00,
0x00, 0x02, 0x03, 0x01, 0x01, 0x03, 0x02, 0x00, 0x02, 0x00, 0x01, 0x03, 0x03, 0x01, 0x00, 0x02,
0x03, 0x01, 0x00, 0x02, 0x02, 0x00, 0x01, 0x03, 0x01, 0x03, 0x02, 0x00, 0x00, 0x02, 0x03, 0x01,
原始问题到此结束。
rcgldr回答后更新:
#include <iostream>
#include <bitset>
#include <iomanip>
void make_crc_table(unsigned int crcTable[])
{
unsigned char POLYNOMIAL = 0xc;
unsigned char remainder;
unsigned char b = 0;
do
{
remainder = b;
for (int bit = 8; bit > 0; --bit)
{
if (remainder & 0x80)
remainder = (remainder << 1) ^ POLYNOMIAL;
else
remainder = (remainder << 1);
}
crcTable[(size_t)b] = remainder;
} while (0 != ++b);
}
int main()
{
unsigned int crcTable[256];
make_crc_table(crcTable);
for (size_t i = 0; i < 256; i++)
{
std::cout << "0x";
std::cout << std::setfill('0') << std::setw(2) << std::hex << (crcTable[i]);
if (i % 16 == 15)
std::cout << "," << std::endl;
else
std::cout << ", ";
}
return 0;
}
代码输出:
0x00, 0x0c, 0x18, 0x14, 0x30, 0x3c, 0x28, 0x24, 0x60, 0x6c, 0x78, 0x74, 0x50, 0x5c, 0x48, 0x44,
0xc0, 0xcc, 0xd8, 0xd4, 0xf0, 0xfc, 0xe8, 0xe4, 0xa0, 0xac, 0xb8, 0xb4, 0x90, 0x9c, 0x88, 0x84,
0x8c, 0x80, 0x94, 0x98, 0xbc, 0xb0, 0xa4, 0xa8, 0xec, 0xe0, 0xf4, 0xf8, 0xdc, 0xd0, 0xc4, 0xc8,
0x4c, 0x40, 0x54, 0x58, 0x7c, 0x70, 0x64, 0x68, 0x2c, 0x20, 0x34, 0x38, 0x1c, 0x10, 0x04, 0x08,
0x14, 0x18, 0x0c, 0x00, 0x24, 0x28, 0x3c, 0x30, 0x74, 0x78, 0x6c, 0x60, 0x44, 0x48, 0x5c, 0x50,
0xd4, 0xd8, 0xcc, 0xc0, 0xe4, 0xe8, 0xfc, 0xf0, 0xb4, 0xb8, 0xac, 0xa0, 0x84, 0x88, 0x9c, 0x90,
0x98, 0x94, 0x80, 0x8c, 0xa8, 0xa4, 0xb0, 0xbc, 0xf8, 0xf4, 0xe0, 0xec, 0xc8, 0xc4, 0xd0, 0xdc,
0x58, 0x54, 0x40, 0x4c, 0x68, 0x64, 0x70, 0x7c, 0x38, 0x34, 0x20, 0x2c, 0x08, 0x04, 0x10, 0x1c,
0x28, 0x24, 0x30, 0x3c, 0x18, 0x14, 0x00, 0x0c, 0x48, 0x44, 0x50, 0x5c, 0x78, 0x74, 0x60, 0x6c,
0xe8, 0xe4, 0xf0, 0xfc, 0xd8, 0xd4, 0xc0, 0xcc, 0x88, 0x84, 0x90, 0x9c, 0xb8, 0xb4, 0xa0, 0xac,
0xa4, 0xa8, 0xbc, 0xb0, 0x94, 0x98, 0x8c, 0x80, 0xc4, 0xc8, 0xdc, 0xd0, 0xf4, 0xf8, 0xec, 0xe0,
0x64, 0x68, 0x7c, 0x70, 0x54, 0x58, 0x4c, 0x40, 0x04, 0x08, 0x1c, 0x10, 0x34, 0x38, 0x2c, 0x20,
0x3c, 0x30, 0x24, 0x28, 0x0c, 0x00, 0x14, 0x18, 0x5c, 0x50, 0x44, 0x48, 0x6c, 0x60, 0x74, 0x78,
0xfc, 0xf0, 0xe4, 0xe8, 0xcc, 0xc0, 0xd4, 0xd8, 0x9c, 0x90, 0x84, 0x88, 0xac, 0xa0, 0xb4, 0xb8,
0xb0, 0xbc, 0xa8, 0xa4, 0x80, 0x8c, 0x98, 0x94, 0xd0, 0xdc, 0xc8, 0xc4, 0xe0, 0xec, 0xf8, 0xf4,
0x70, 0x7c, 0x68, 0x64, 0x40, 0x4c, 0x58, 0x54, 0x10, 0x1c, 0x08, 0x04, 0x20, 0x2c, 0x38, 0x34,
最佳答案
位顺序很重要。问题的代码使用反射的输入和输出。这意味着多项式应从0x03反转为0x0c。为了确认这一点,表条目[0x80]应为0x0c。
对于Interlaken表,代码应如下所示:
void make_crc_table(unsigned char crcTable[])
{
unsigned char POLYNOMIAL = 0x30;
unsigned char remainder;
unsigned char b = 0;
do
{
remainder = b;
for (int bit = 8; bit > 0; --bit)
{
if (remainder & 0x80)
remainder = (remainder << 1) ^ POLYNOMIAL;
else
remainder = (remainder << 1);
}
crcTable[(size_t)b] = remainder;
} while (0 != ++b);
}
注意,CRC将在字节的高4位中。完成后,代码将需要返回(crc >> 4)^ 0x0f。
关于c++ - CRC4 INTERLAKEN和ITU查找表生成,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/62201937/