Существует множество примеров расчета CRC. Простые реализации с битовым сдвигом и более эффективными с предварительно рассчитанной таблицей. Но также есть много параметров CRC рядом с полиномом, которые влияют на расчет. Вы можете оценить эти параметры здесь: http://zorc.breitbandkatze.de/crc.htmlКак настроить расчет таблицы CRC
Этих параметров
- начального значение CRC
- отражения входных данных
- отражения выходных данных
- конечного значения XOR для CRC
Для некоторого «стандартного» алгоритма CRC эти параметры хорошо определены, например CRC-16 (CCITT). Но есть некоторые реализации, которые используют разные параметры.
Моя реализация должна быть совместима с CRC16 с CCITT полинома (х + х + х + 1). Но байты данных и окончательный CRC должны быть отражены. Я реализовал это отражение в методе расчета. Но это требует много времени. Для лучшей производительности его необходимо удалить из расчета.
Как можно вычислить параметры отражения CRC в методе инициализации?
Редактировать: Как мне сделать, чтобы контролировать каждый из параметров отдельно? Я хотел бы понять, как работает функция Init
и как все параметры реализованы.
typedef unsigned char uint8_t;
typedef unsigned short crc;
crc crcTable[256];
#define WIDTH (8 * sizeof(crc))
#define TOPBIT (1 << (WIDTH - 1))
#define POLYNOMIAL 0x1021
template<typename t>
t reflect(t v)
{
t r = 0;
for (int i = 0; i < (8 * sizeof v); ++i)
{
r <<= 1;
r |= v&1;
v >>= 1;
}
return r;
}
void Init()
{
crc remainder;
for (int dividend = 0; dividend < 256; ++dividend)
{
remainder = dividend << (WIDTH - 8);
for (uint8_t bit = 8; bit > 0; --bit)
{
if (remainder & TOPBIT)
remainder = (remainder << 1)^POLYNOMIAL;
else
remainder = (remainder << 1);
}
crcTable[dividend] = remainder;
}
}
crc Calculate(const uint8_t *message, int nBytes, crc wOldCRC)
{
uint8_t data;
crc remainder = wOldCRC;
for (int byte = 0; byte < nBytes; ++byte)
{
data = reflect(message[byte])^(remainder >> (WIDTH - 8));
remainder = crcTable[data]^(remainder << 8);
}
return reflect(remainder);
}
int main()
{
crc expected = 0x6f91;
uint8_t pattern[] = "123456789";
Init();
crc result = Calculate(pattern, 9, 0xFFFF);
if (result != expected)
{
// this output is not relevant to the question, despite C++ tag
printf("CRC 0x%04x wrong, expected 0x%04x\n", result, expected);
}
}
Ничего общего с входными данными не является «параметром CRC». Параметрами являются полином, начальное значение и ширина бита. – EJP
@EJP Итак, вы сказали бы, что информация на приведенной мной странице неверна? Но вы согласны с тем, что изменение параметров влияет на результат CRC, не так ли? – harper