如何根据lookup table生成CRC7?
How to generate CRC7 based on lookup table?
我正在尝试使用预生成的查找 table 实现 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。我使用 this website 来检查输出。
任何建议或想法都将受到高度赞赏。谢谢
请注意,您指向的 CRC 定义包括 refin=false refout=false
。该 CRC 未反映出来,因此它是通过左移而不是右移计算的。
考虑到 CRC 的长度小于八位,您还需要将七位保留在所用字节的 top计算,而不是底部。 IE。位 1 到 7,而不是位 0 到 6。然后多项式也向上移动一位以进行 table 计算。
这允许 table-driven、byte-wise 计算将每个消息字节 exclusive-or 简单地转换为用于计算的字节。如果要return低七位的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';
}
根据定义,crcany 将为您生成 CRC 代码。由于您的 CRC-7/MMC 在 Greg 的目录中,crcany 将立即生成该代码,以及其中定义的其他 100 多个 CRC。生成的代码包括 bit-wise、byte-wise 和 word-wise 计算。
我正在尝试使用预生成的查找 table 实现 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。我使用 this website 来检查输出。 任何建议或想法都将受到高度赞赏。谢谢
请注意,您指向的 CRC 定义包括 refin=false refout=false
。该 CRC 未反映出来,因此它是通过左移而不是右移计算的。
考虑到 CRC 的长度小于八位,您还需要将七位保留在所用字节的 top计算,而不是底部。 IE。位 1 到 7,而不是位 0 到 6。然后多项式也向上移动一位以进行 table 计算。
这允许 table-driven、byte-wise 计算将每个消息字节 exclusive-or 简单地转换为用于计算的字节。如果要return低七位的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';
}
根据定义,crcany 将为您生成 CRC 代码。由于您的 CRC-7/MMC 在 Greg 的目录中,crcany 将立即生成该代码,以及其中定义的其他 100 多个 CRC。生成的代码包括 bit-wise、byte-wise 和 word-wise 计算。