Понимание циклических полиномиальных хэш-коллизий

У меня есть код, который использует циклический полиномиальный скользящий хеш (Бужаш) для вычисления хэш-значений n-граммов исходного кода. Если я использую небольшие хэш-значения (7-8 бит), то возникают некоторые коллизии, т.е. разные n-граммы сопоставляются с одним и тем же значением хеш-функции. Если я увеличу биты в хеш-значении, скажем, до 31, то будет 0 коллизий - все ngrams сопоставляются с разными хэш-значениями.

Я хочу знать, почему это так? Зависят ли коллизии от количества n-грамм в тексте или количества различных символов, которые может иметь n-грамма, или это размер n-граммы?

Как выбрать количество битов для хеш-значения при хешировании n-грамм (используя скользящие хэши)?


person csprajeeth    schedule 03.05.2013    source источник
comment
Рискуя выдать свое полное невежество... разве меньшие хеш-значения не всегда чаще сталкиваются? (При прочих равных (так сказать), то есть тот же алгоритм.)   -  person harpo    schedule 03.05.2013


Ответы (2)


Как длина влияет на коллизии

Это просто вопрос перестановок.

Если я использую небольшие хеш-значения (7-8 бит), то возникают некоторые коллизии.

Что ж, давайте проанализируем это. С 8 битами существует 2^8 возможных двоичных последовательностей, которые могут быть сгенерированы для любого заданного входа. Это 256 возможных хеш-значений, которые могут быть сгенерированы, что означает, что теоретически каждые 256 сгенерированных значения дайджеста сообщения гарантируют коллизию. Это называется проблемой дня рождения.

Если я увеличу биты в хеш-значении, скажем, до 31, то будет 0 коллизий - все ngrams сопоставляются с разными хэш-значениями.

Что ж, давайте применим ту же логику. С 31-битной точностью у нас есть 2^31 возможных комбинаций. Это 2147483648 возможных комбинаций. И мы можем обобщить это на:

Let N denote the amount of bits we use.
Amount of different hash values we can generate (X) = 2^N

Assuming repetition of values is allowed (which it is in this case!)

Это экспоненциальный рост, поэтому с 8 битами вы обнаружили много коллизий, а с 31 битами — очень мало столкновений.

Как это влияет на коллизии?

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

Let A denote the number of different values already generated.
Chance of a collision is: A / X 

Where X is the possible number of outputs the hashing algorithm can generate.

Когда X равняется 256, у вас есть 1/256 вероятность столкновения в первый раз. Тогда у вас есть 2/256 шанс столкновения, когда генерируется другое значение. Пока, в конце концов, вы не сгенерируете 255 различных значений, и у вас будет 255/256 вероятность столкновения. В следующий раз, очевидно, это станет 256/256 шансом, или 1, что является вероятностной уверенностью. Понятно, что обычно до этого не доходит. Столкновения, скорее всего, будут происходить гораздо чаще, чем каждые 256 циклов. На самом деле, парадокс дня рождения говорит нам, что мы можем начать ожидать коллизии после того, как будет сгенерировано 2^N/2 значений дайджеста сообщения. Следуя нашему примеру, мы создали 16 уникальных хэшей. Однако мы знаем, что это должно происходить минимум каждые 256 циклов. Что не хорошо!

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

Примечание об алгоритмах хеширования

Столкновения совершенно неизбежны. Это связано с тем, что существует чрезвычайно большое количество возможных входных данных (2 ^ Все возможные коды символов) и конечное количество возможных выходных данных (как показано выше).

person christopher    schedule 06.05.2013
comment
Придирка: количество возможных входов может быть очень большим, но оно не бесконечно. - person MiMo; 06.05.2013
comment
Справедливости ради, это ограничено количеством возможных кодов символов, которые мы можем ввести. Поправки. - person christopher; 06.05.2013
comment
Возможно, вы захотите упомянуть парадокс дня рождения: вам нужно всего лишь хешировать около 2 ^ (N/2) значений с помощью N-битного хеша, прежде чем вы должны ожидать коллизии. - person templatetypedef; 06.05.2013
comment
Думаю, я могу. Кажется, слишком много подробностей, учитывая тему вопроса, но почему бы и нет. - person christopher; 06.05.2013

Если у вас есть хеш-значения из 8 бит, общее возможное количество значений равно 256 - это означает, что если вы хэшируете 257 различных n-грамм, то наверняка будет по крайней мере одно столкновение (... и, скорее всего, вы получите гораздо больше коллизий , даже с менее чем 257 n-граммами) - и это произойдет независимо от алгоритма хеширования или хэшируемых данных.

Если вы используете 32 бита, общее возможное количество значений составляет около 4 миллиардов, поэтому вероятность коллизии намного меньше.

«Как выбрать количество битов»: я думаю, зависит от использования хэша. Если он используется для хранения n-грамм в какой-либо хешированной структуре данных (словаре), то он должен быть связан с возможным количеством «сегментов» структуры данных, например. если в словаре меньше 256 сегментов, то 8-битный хэш подходит.

См. этодля фона

person MiMo    schedule 06.05.2013