Как уменьшить хэш?

Предположим, у меня есть какой-нибудь «длинный» хэш, например 16-байтовый MD5 или 20-байтовый SHA1. Я хочу уменьшить этот хэш до 4 байтов для целей GetHashCode().

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

Есть несколько решений моей проблемы:

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

Есть ли другие решения, о которых я не подумал? И что еще более важно, какой метод даст мне самый уникальный хэш-код? В настоящее время я предполагаю, что они почти эквивалентны.

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


person Julien Lebosquain    schedule 13.06.2010    source источник


Ответы (5)


Любой хэш — это уже сокращение.

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

person Ben Voigt    schedule 13.06.2010

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

person Guffa    schedule 13.06.2010
comment
Конечно, я думал о «жестко закодированном» рандоме. Спасибо за ваш отзыв. - person Julien Lebosquain; 13.06.2010

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

Я бы просто выбрал первые 4 байта — SHA1 разработан таким образом, что никакие байты не должны быть такими же важными, как любой другой набор байтов.

person Callum Rogers    schedule 13.06.2010
comment
Вы имели в виду, что ни один байт не должен быть более важным, чем любой другой набор? - person Ben Voigt; 13.06.2010

Если у вас есть разумное количество хэшей, проиндексируйте их (например, сохраните в базе данных):

1 - 987baf9gfd79b7979debe90085eadf5
2 - 9754gccgfd79s7979abbc90085eadf5
...
person takeshin    schedule 13.06.2010

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

Любое использование?

person Adam Houldsworth    schedule 13.06.2010