Подтвердить что ты не робот

Может ли CRC32 использоваться как хэш-функция?

Может ли CRC32 использоваться как хэш-функция? Какие-либо недостатки такого подхода? Любые торговые предложения?

4b9b3361

Ответ 1

CRC32 отлично работает как хэш-алгоритм. Вся точка CRC состоит в хэш-потоке байтов с как можно меньшим количеством коллизий. Тем не менее, есть несколько моментов, которые следует учитывать:

  • CRC небезопасны. Для безопасного хэширования вам нужен гораздо более дорогостоящий алгоритм. Для простого ведро-хэширования безопасность обычно не является проблемой.

  • Различные ароматы CRC существуют с различными свойствами. Убедитесь, что вы используете правильный алгоритм, например. с хэш-полиномом 0x11EDC6F41 (CRC32C), который является оптимальным выбором общего назначения.

  • Как компромисс между скоростью хеширования и качеством, команда x86 CRC32 трудно превзойти. Однако эта инструкция не существует в более старых процессорах, поэтому будьте осторожны с проблемами переносимости.

---- EDIT ----

Марк Адлер предоставил ссылку на полезную статью для оценки хэша Брет Малвей. Используя исходный код, приведенный в статье, я выполнил "тест ведра" для CRC32C и Jenkins96. Эти таблицы показывают вероятность того, что по-настоящему равномерное распределение будет хуже, чем измеренный результат случайно. Таким образом, более высокие цифры лучше. Автор считал, что 0,05 или ниже слабый и 0,01 или ниже, чтобы быть очень слабым. Я полностью доверяю автору обо всем этом и просто сообщаю результаты.

Я поместил * все экземпляры, где CRC32C работал лучше, чем Jenkins96. По этой простой подсчету CRC32C был более однородным хешем, чем Jenkins96 54 из 96 раз. Особенно, если вы можете использовать инструкцию x86 CRC32, компромисс скорости производительности превосходный.

CRC32C (0x1EDC6F41)

       Uniform keys        Text keys         Sparse keys

Bits  Lower    Upper     Lower    Upper     Lower    Upper
 1    0.671   *0.671    *1.000    0.120    *0.572   *0.572
 2   *0.706   *0.165    *0.729   *0.919     0.277    0.440
 3   *0.878   *0.879    *0.556    0.362    *0.535   *0.542
 4    0.573    0.332     0.433    0.462    *0.855    0.393
 5    0.023   *0.681     0.470    0.907     0.266    0.059
 6   *0.145   *0.523     0.354   *0.172    *0.336    0.588
 7    0.424    0.722     0.172   *0.736     0.184   *0.842
 8   *0.767    0.507    *0.533    0.437     0.337    0.321
 9    0.480    0.725    *0.753   *0.807    *0.618    0.025
10   *0.719    0.161    *0.970   *0.740    *0.789    0.344
11   *0.610    0.225    *0.849   *0.814    *0.854   *0.003
12   *0.979   *0.239    *0.709    0.786     0.171   *0.865
13   *0.515    0.395     0.192    0.600     0.869   *0.238
14    0.089   *0.609     0.055   *0.414    *0.286   *0.398
15   *0.372   *0.719    *0.944    0.100    *0.852   *0.300
16    0.015   *0.946    *0.467    0.459     0.372   *0.793

И для Jenkins96, который автор статьи считал отличным хешем:

Jenkins96

      Uniform keys         Text keys         Sparse keys

Bits  Lower    Upper     Lower    Upper     Lower    Upper
 1    0.888    0.572     0.090    0.322     0.090    0.203
 2    0.198    0.027     0.505    0.447     0.729    0.825
 3    0.444    0.510     0.360    0.444     0.467    0.540
 4    0.974    0.783     0.724    0.971     0.439    0.902
 5    0.308    0.383     0.686    0.940     0.424    0.119
 6    0.138    0.505     0.907    0.103     0.300    0.891
 7    0.710    0.956     0.202    0.407     0.792    0.506
 8    0.031    0.552     0.229    0.573     0.407    0.688
 9    0.682    0.990     0.276    0.075     0.269    0.543
10    0.382    0.933     0.038    0.559     0.746    0.511
11    0.043    0.918     0.101    0.290     0.584    0.822
12    0.895    0.036     0.207    0.966     0.486    0.533
13    0.290    0.872     0.902    0.934     0.877    0.155
14    0.859    0.568     0.428    0.027     0.136    0.265
15    0.290    0.420     0.915    0.465     0.532    0.059
16    0.155    0.922     0.036    0.577     0.545    0.336

Ответ 2

Очевидно, вы могли бы, но не должны. Crc32 плохо распределяет входные биты в хеш. Также он никогда не должен использоваться как односторонний хеш, поскольку он не один. Очень легко изменить сообщение для создания заданного crc.

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

Ответ 3

Я не знаю, почему Марк Адлер сказал, что "crc32 плохо распределяет входные биты в хеш". В хеше crc32 нет единственного бита, который точно равен входным битам. Любой бит хэша представляет собой линейную комбинацию входных битов. Во-вторых, crc всегда равномерно сопоставляет одинаковое количество различных входных последовательностей с заданным значением хэша. Например, если у вас есть сообщение длиной 1000 бит, после crc32 вы всегда можете найти 2 ^ (1000-32) последовательности, которые генерируют заданное значение хэша, не более, не менее.

Если вам не нужна функция безопасности, crc может отлично служить хешем.

На самом деле, я думаю, что другие небезопасные хэш-функции могут быть проще, чем crc, если вам нужно иметь более длинный crc, например crc-256.