Хэширование алгоритмом CRC

437
03 февраля 2017, 04:34

Объясните как работает этот алгоритм ибо хорошей, понятной информации по этому алгоритму я не нашел. Все описывают в математических формулах, а я хочу понять саму суть алгоритма. То как он работает, а в частности, что он он делает с поступившими данными.

Answer 1

Задача crc очень проста - в соответствии с поступившими байтами поставить им в соответствие 4 байта (или 2, crc бывают разные). При этом выполняются следующие условия:

  • у одинаковых входных данных будет одинаковый crc.
  • у разных входных данных будет разный crc, но может быть и одинаковый.
  • у входных данных, которые отличаются совсем немножко (несколько бит), скорее всего будут разные crc.

Само вычисление описано в википедии и в конце концов сводиться к математическим формулам. Но если отбросить все это, то в сухом остатке остается в основном xor и сдвиг. То есть, с входного потока читаем данные, сдвигаем/ксорим.

Возьмем в википедии очень простой crc8 и разберем

/*
  Name  : CRC-8
  Poly  : 0x31    x^8 + x^5 + x^4 + 1 - над его выбором сидят математики и криптоаналитики
  Init  : 0xFF над этим также
  Revert: false
  XorOut: 0x00
  Check : 0xF7 ("123456789") контрольное значение, что бы проверить реализацию
  MaxLen: 15 байт(127 бит) - обнаружение
    одинарных, двойных, тройных и всех нечетных ошибок
*/
unsigned char Crc8(unsigned char *pcBlock, unsigned int len)
{
    // начальное значение. Выбирается с потолка или экспериментально
    unsigned char crc = 0xFF; 
    unsigned int i;
    while (len--) // пока у нас есть данные
    {
        crc ^= *pcBlock++; // ксорим очередной байт
        for (i = 0; i < 8; i++) 
            // применяем полином. тут просто ксорим и/или сдвигаем.
            crc = crc & 0x80 ? (crc << 1) ^ 0x31 : crc << 1;
    }
    return crc;
}

В принципе, если полином пуст, то результат это просто последовательно проксоренные байты (для crc8) или int'ы (для crc32).

В википедии описаны разлиные значения полиномов и начальных значний (все те магические константы) для различных модификаций алгорима. Какое выбрать - это сложная задача, тут математики пусть сидят и думают. Для своих приложений главное, чтобы с двух сторон был один и тот же алгоритм.

READ ALSO
как нарисовать SVG Elliptical Arcs

как нарисовать SVG Elliptical Arcs

Пытаюсь понять как преобразовать данные для прорисовки эллипса из svg к виду для прорисовки в addArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle)Все...

367
Ошибка при создании массива generics

Ошибка при создании массива generics

Предположим, есть такой код:

411
Как использовать Graphics в Java? [требует правки]

Как использовать Graphics в Java? [требует правки]

Как использовать Graphics в Java?

329
Исключения при работе с сервлетом [требует правки]

Исключения при работе с сервлетом [требует правки]

здравствуйте,есть код который нормально компилируется javase,когда хочу вызвать этот код в javaee в сервлете вылетает ошибка NullPointerException почему...

304