[an error occurred while processing this directive]
|
carry = (crc >> 8) ^ byte;
carry = carry ^ (carry >> 4);
return (crc << 8) ^ (carry << 12) ^ (carry << 5) ^ carry ;
Отсюда видно - первые две строки это вычисление байта "переноса", то есть того байта, который получится в битах 23..16 результата после 8 итераций сдвигов и условных ксоров "в лоб". Сдвиг на 4 вправо - это эквивалент сдвига на 12 влево (запчасть 0х1000 от полинома 0х1021), а затем на 16 вправо (для получения битов 23..16).
А последняя строка - это "свернутый цикл" - вместо того, чтобы анализировать каждый раз старший бит и ксорить или нет с полиномом, берем байт переноса, сдвигаем его на позиции, определенные полиномом (12 - 0x1000, 5 - 0x0020, без сдвига - 0x0001), и перексориваем вместе со сдвинутым на 8 исходным CRC. Итого получаем эквивалент операции "в лоб", то есть инвертируются биты в нужных позициях, где в переносе была единица, и не инвертируются, где в переносе был ноль.