我必须将一个人的姓氏,名字和出生日期的组合保存为哈希。此哈希稍后用于搜索具有完全相同属性的同一个人。 我的问题是,如果SHA-1是一个有意义的算法。
据我了解SHA-1,两个不同的人(具有不同属性)几乎不可能获得相同的哈希值。这是对的吗?
答案 0 :(得分:1)
如果您想搜索知道仅这些凭据的人,您可以将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 %
我非常确定你不会发生碰撞;)
答案 1 :(得分:1)
哈希碰撞是不可避免的。然而,小的可能是碰撞的机会,如果你真的想要100%识别,你不应该只依赖哈希。
如果使用散列来加速数据库搜索,则无需使用SHA256。使用你的系统具有最小尺寸的任何哈希函数(MD5()用于MySQL,或者你甚至可以尝试CRC32,如果你的数据库不是那么大)。就在您查询表时,您需要提供您要搜索的所有条件:
SELECT *来自用户WHERE hash =“AABBCCDD”AND firstname =“Pavel”AND surname =“Sokolov”
数据库维护一个名为index cardinality的值。它衡量给定指数数据的唯一性。因此,您可以将所需的字段与哈希字段和数据库一起索引,并为查询本身选择最具选择性的索引。添加附加条件不会对性能产生负面影响,因为大多数数据库在从表中选择数据时只能使用一个索引,并且会选择具有最大基数值的数据。
数据库需要首先选择与索引匹配的所有行,然后扫描它们以丢弃与其他条件不匹配的行。
如果你不能使用我描述的方法,那么,我认为甚至MD5的碰撞概率在人名数据库上也很低。
P.S。我希望你知道,你知道“一个人的姓氏,名字和出生日期的组合”不足以100%识别一个人吗?很快这个组合就会比一些哈希碰撞而匹配。
答案 2 :(得分:0)