我试图用预生成的查找表实现CRC-7/MMC校验和。这是目前为止的代码:
#include <iostream>
#include <string>
#include <cstdint>
using namespace std;
/* CRC-7/MMC
Poly: 0x09
Xorout: NO
Init: 0x00
Check value: 0x75 for "123456789"
*/
uint16_t CRC7_table[256];
void generate_crc7_table() {
uint16_t byte;
for (uint16_t i = 0; i < 256; i++) {
byte = i;
for (uint16_t bit = 0; bit < 8; bit++) {
if (byte & 1) { //if lsb is 1
byte >>= 1;
byte ^= 0x09;
}
else
byte >>= 1;
}
CRC7_table[i] = byte >> 1; //to drop off MSB
}
}
uint16_t crc7(string input) {
uint16_t reg = 0;
uint16_t b;
for (uint16_t i = 0; i < input.length(); i++) {
b = (input[i] ^ reg) & 0xFF;
reg = (reg >> 1) ^ CRC7_table[b];
}
return reg;
}
int main()
{
generate_crc7_table();
cout << hex << crc7("123456789") << endl;
return 0;
}但它提供了错误的输出。我应该得到0x75,但我得到0x07。我使用本网站来检查输出。任何建议或想法都会受到高度赞赏。谢谢。
发布于 2022-05-10 15:31:26
请注意,您所指向的CRC定义包括refin=false refout=false。CRC没有被反映,所以它是用左移位而不是右移位来计算的。
考虑到这一点,以及CRC长度小于8位的事实,您还需要将7位保存在用于计算的字节的顶部,而不是底部。即第1位到第7位,而不是0到6位。然后,在表计算中,多项式也被向上移动1。
这使得表驱动的、按字节进行的计算可以简单地排它--或者将每个消息字节变成用于计算的字节。如果您想返回低7位的CRC,您可以在最后将其向下移动一位。
示例(0x12是0x09向上移动了一个):
#include <iostream>
#include <string>
uint8_t table[256];
void make_table() {
uint8_t octet = 0;
do {
uint8_t crc = octet;
for (int k = 0; k < 8; k++)
crc = crc & 0x80 ? (crc << 1) ^ 0x12 : crc << 1;
table[octet++] = crc;
} while (octet);
}
uint8_t crc7(std::string const& input) {
uint8_t crc = 0;
for (auto octet : input)
crc = table[crc ^ octet];
return crc >> 1;
}
int main() {
make_table();
std::cout << std::hex << (unsigned)crc7("123456789") << '\n';
}给定定义,克拉卡尼将为您生成CRC代码。由于您的CRC-7/MMC在格雷格的目录中,crcany将与在那里定义的其他100+ CRC一起生成该代码。生成的代码包括按位计算、按字节计算和按单词计算.
https://stackoverflow.com/questions/72187797
复制相似问题