Примечание: я не пытаюсь использовать SuperFastHash и ожидаю, что он выдаст те же выходные значения, что и CRC32.
Я пишу простое LZSS Процедура сжатия / распаковки, обеспечивающая очень быструю распаковку и не требующую дополнительной памяти при распаковке.Входные данные разбиваются на блоки длиной 4096 байт и сжимаются последовательно.
Моя проблема: я хочу добавить обнаружение ошибок для каждого сжатого блока (размер блока <= 4096 байт).Время ограничено, и поэтому процедура контрольной суммы должна быть очень быстрой.Я избегал криптографических алгоритмов (MD5, SHA1), потому что они требуют большого количества вычислений, и я выбрал CRC32 (более простой и очевидный алгоритм).</p>
После нескольких тестов я обнаружил, что CRC32 слишком медленный в отношении ограничений моего проекта.Я использовал enwik9 (10 ^ 9-байтовый текстовый дамп википедии) из здесь .Я сжал его, используя мою подпрограмму LZSS, и получил файл 570Mb.Я измерил следующие длительности (однопоточный, исключая дисковый ввод-вывод, все данные, загруженные в память перед обработкой, в среднем из 10 испытаний):
| Operation | Time (GCC4.4.5/Linux) | Time (MSVC2010/Win7) |
|-------------------------------+--------------------------+------------------------|
| Decompression | 6.8 seconds | 6.95 seconds |
| CRC32 on decompressed result | 4.9 seconds | 4.62 seconds |
| CRC32 on compressed result | 2.8 seconds | 2.69 seconds |
Затем я протестировал SuperFastHash, просто из любопытства:
| Operation | Time (GCC4.4.5/Linux) | Time (MSVC2010/Win7) |
|-------------------------------+--------------------------+------------------------|
| SFH on decompressed result | 1.1 seconds | 1.33 seconds |
| SFH on compressed result | 0.7 seconds | 0.75 seconds |
А вот моя реализация CRC32 (я следовал описаниям из следующего документа: http://www.ross.net/crc/download/crc_v3.txt):
# include <stdint.h>
// CRC32 lookup table (corresponding to the polynom 0x04C11DB7)
static const uint32_t crc32_lookup_table[256] =
{
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
// many lines skipped
// ...
0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
} ;
uint32_t crc32_hash(const uint8_t * data, size_t len)
{
uint32_t crc32_register = 0xFFFFFFFF ;
while( len-- )
{
crc32_register = (crc32_register >> 8)
^ crc32_lookup_table[(crc32_register & 0x000000FF) ^ *data++] ;
}
return crc32_register ^ 0xFFFFFFFF ;
}
Мой вопрос:
Могу ли я использоватьхэш вместо значения проверки циклическим избыточным кодом для обнаружения ошибок в сжатых блоках данных? Насколько я знаю (и я помню из моего курса электроники), алгоритмы CRC спроектированы так, чтобы быть очень эффективными, когда в пакетах возникают ошибки, когда данные передаются черезшумный канал, который не используется для чтения данных с жестких дисков. Пожалуйста, исправьте меня, если я ошибаюсь.
Спасибо за любой совет!