Я много раз пытался написать свою собственную реализацию CRC32 в соответствии с теорией, но я так и не получил ожидаемых результатов.
Сегодня я сделал еще одну попытку, ссылаясь не только на теорию, но и на реализацию Boosts. Хотя, наконец, я все заработал правильно, я не понимаю, почему это так работает.
Я понимаю, почему boost обращает байт и обращает результат, я знаю, почему его начальный остаток равен 0xffffffff, и результат должен быть XOR с 0xffffffff. Это стандарт.
Но когда дело доходит до функции ProcessBit
Я застрял.
В ответ на Как рассчитывается контрольная сумма CRC32?, Я нашел полный пример. Поэтому я думаю, что реализация ProcessBit
выглядит так:
void CRC32::ProcessBit(bool b)
{
/*
x xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxb : x curVal, b coming bit
1 yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy : y polynomial
*/
if (_remainder & 0x80000000) {
_remainder <<= 1;
_remainder |= b;
_remainder ^= polynomial;
} else {
_remainder <<= 1;
_remainder |= b;
}
}
Так как первый бит полинома равен 1, если остаток начинается с бита 1, я его XOR. Но эта реализация дает неверный результат. Я проследил код в Boost, чтобы увидеть, как он работает, и написал свой собственный:
void CRC32::ProcessBit(bool b)
{
bool high = (_remainder & 0x80000000) ? true : false;
_remainder <<= 1;
if (high != b) {
_remainder ^= polynomial;
}
}
Эта реализация работает хорошо. но я не понимаю почему. Что меня смущает, так это то, что условие для определения того, должен ли остаток быть XOR с полиномом:
«первый бит остатка равен грядущему».
Тогда как в «полном примере» используется другое условие, а именно:
msgstr «первый бит остатка равен 1».
Другой вопрос; почему следующий бит не будет добавлен в конце остатка в реализации Boost.
Редактировать:
Я решил проблему. Причина, по которой он дал неправильный результат, заключается в том, что я неправильно понимаю значение «начальная стоимость».
Задача ещё не решена.
Других решений пока нет …