Какой алгоритм для хэширования имени, имени и даты рождения человека

Я должен сохранить комбинацию фамилии, имени и даты рождения человека в виде хэша. Этот хэш позже используется для поиска того же человека с точно такими же свойствами. Мой вопрос заключается в том, является ли SHA-1 значимым алгоритмом для этого.

Насколько я понимаю SHA-1, практически нет возможности, что два разных человека (с разными атрибутами) когда-либо получат одинаковое значение хеш-функции. Это правильно?

3 ответа

Решение

Если вы хотите найти человека, знающего только эти учетные данные, вы можете сохранить SHA-1 в базе данных (или MD5 для скорости, если у вас нет образца, подобного квадриллиону).

Хеш будет бесполезным, так как не хранит информацию о человеке, но может работать для поиска в базе данных. Вы просто хотите убедиться, что три фрагмента информации совпадают, поэтому было бы безопасно просто объединить их:

user.hash = SHA1(user.firstName + user.DOB + user.lastName)

И когда вы делаете запрос, вы можете проверить, совпадают ли два:

hash = SHA1(query.firstName + query.DOB + query.lastName)

for user in database:
  if user.hash == hash:
    return user

я кладу query.DOB в середине, потому что имя и фамилия могут сталкиваться, как если бы JohnDoe Bob родился в тот же день, что и John DoeBob, Я не знаю о числовых именах, так что я думаю, что это остановит такие коллизии;)

Но если это большая база данных, я бы попробовал MD5. Это быстрее, но есть вероятность столкновения (в вашем случае я могу гарантировать, что оно не произойдет). Однако вероятность столкновения действительно мала.

Чтобы поместить это в перспективу, столкновение является 1 / 2^128 вхождение, которое:

                          1
---------------------------------------------------
340,282,366,920,938,463,463,374,607,431,768,211,456

И это немного меньше, чем:

0.0000000000000000000000000000000000000293873 %

Я уверен, что вы не получите столкновение;)

Хеш-коллизии неизбежны. Каким бы небольшим ни был шанс столкновения, на самом деле не стоит полагаться только на хеш, если вы действительно хотите 100% -ную идентификацию.

Если вы используете хеширование для ускорения поиска в базе данных, вам не нужно использовать SHA256. Используйте любую хеш-функцию, которую ваша система имеет наименьший размер (MD5() для MySQL, или вы даже можете попробовать CRC32, если ваша база данных не такая уж большая). Когда вы запрашиваете таблицу, вам нужно указать все условия, по которым вы ищете:

SELECT * от пользователя WHERE hash="AABBCCDD" AND firstname="Pavel" AND surname="Sokolov"

Базы данных поддерживают значение, которое называется индексом кардинальности. Это мера уникальности данных по данному индексу. Таким образом, вы можете индексировать нужные поля вместе с полем хеша, и база данных сама выберет наиболее селективный индекс для запроса. Добавление дополнительных условий не влияет отрицательно на производительность, так как большинство баз данных могут использовать только один индекс при выборе данных из таблицы, и они выберут тот, который имеет наибольшее значение мощности.

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

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

PS Надеюсь, вы знаете, что вы знаете, что "сочетание фамилии, имени и даты рождения человека" недостаточно для того, чтобы на 100% идентифицировать человека? И скорее эта комбинация совпадет, чем столкнутся некоторые хеши.

Если вы беспокоитесь о столкновениях, здесь есть хорошее обсуждение:

Понимание слабости столкновения ша-1

Если у вас есть проблемы с безопасностью, я бы рассмотрел SHA-256 вместо этого.

Другие вопросы по тегам