вычисление CRC «на лету», возможно или нет

#hash #crc #crc32

#хэш #crc #crc32

Вопрос:

Возможно ли вычислить CRC «на лету» (в потоках)?

Например, у меня есть данные объемом 1 гигабайт, и я хочу уменьшить вероятность необнаруженных ошибок. Я хочу реализовать что-то (CRC или хэш) по всему файлу (я уже реализовал CRCS для каждого фрагмента, который содержит некоторые пакеты),

Когда мы помещаем CRC поверх всего файла, возможно ли начать вычислять CRC, как только у нас будет первый пакет, или нам нужно дождаться получения всего файла, а затем начать вычислять CRC?

Ответ №1:

Да. CRC и каждый хэш, о котором я знаю, являются потоковыми. Они имеют небольшое конечное состояние, которое обновляется по мере прохождения через них данных. Для CRC состояние является самим CRC.

CRC в zlib принимает такую форму:

 unsigned long crc32(unsigned long crc, const unsigned char *buf, unsigned len);
  

Когда buf есть NULL , возвращается начальный CRC. Поэтому он используется следующим образом:

 unsigned long crc = crc32(0, NULL, 0);    // initial CRC
for (...) {                               // some sort of loop
    ...                                   // generating a chunk of data
    crc = crc32(crc, buf, len);           // update the CRC with the data
    ...                                   // this all gets repeated many times
}
...                                       // loop is done, crc has the CRC
  

Комментарии:

1. Но чтобы обеспечить целостность данных, нам нужно дождаться получения последнего пакета и обновить состояние CRC. Это верно?

2. @Arash — правильно. Использование одного CRC для 1 гигабайта данных потребовало бы повторной передачи всего 1 гигабайта данных. Разделение данных на более мелкие части с указанием CRC для каждой части имело бы больше смысла. Если частота ошибок и размер сообщения сочетаются таким образом, что происходит значительное количество повторных передач, то код исправления ошибок будет иметь больше смысла, чем CRC.

3. Вы можете сделать и то, и другое. Вы можете вычислять CRC для пакетов данных, а также вычислять CRC для всего этого. Последнее помогает убедиться, что у вас есть все пакеты и что они расположены в правильном порядке. Это практически не занимает больше времени на вычисления, используя, например, crc32_combine() в zlib.

4. Все они, насколько я знаю. В общем случае вы хотите избежать сохранения всего файла в памяти. Возможно, у вас даже не так много памяти. Таким образом, обработка передает данные в потоковом режиме, требуя вычисления CRC по частям за раз.

5. @Arash Не для комментариев — задайте новый вопрос.