Я пытаюсь реализовать контрольную сумму 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. Я использовал этот сайт для проверки результатов. Любое предложение или идея высоко ценится. Спасибо.





Обратите внимание, что определение CRC, на которое вы указали, включает refin=false refout=false. Этот CRC не отражается, поэтому он вычисляется со сдвигом влево, а не вправо.
Учитывая это, а также тот факт, что CRC имеет длину менее восьми бит, вы также захотите сохранить семь битов в верхняя байта, используемого для вычисления, а не в нижней части. т.е. биты с 1 по 7, а не биты с 0 по 6. Затем многочлен также сдвигается вверх на единицу для расчета таблицы.
Это позволяет таблично-управляемому побайтовому вычислению просто исключать каждый байт сообщения из байта, используемого для вычислений. Если вы хотите вернуть 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, определенными там. Сгенерированный код включает побитовые, побайтовые и пословные вычисления.