【发布时间】:2012-05-17 01:38:49
【问题描述】:
我有由字母、数字和特殊字符(电子邮件地址)组成的唯一可变长度字符串列表。列表中的每个电子邮件地址都是唯一的。
我需要一个单向散列函数(我不需要能够从生成的数字中检索原始值),它将用盐对字符串进行散列并生成一个 12 位数字。
我想确保唯一性,因此我将检查先前生成的值列表以检测冲突,然后在发生冲突时生成一个新数字。可预测性不是问题。
理想情况下,我希望这个函数用 Groovy 编写,但 Java 也可以。
【问题讨论】:
-
您正在寻找perfect hash,只要输入字符串少于可能的输出字符串(在您的情况下为 10^12),它就始终存在。但是,生成的哈希函数是特定于该特定数据集的;您不能在不同的数据集上使用它并仍然保证唯一性。
-
我已经更改了生成值不必保证是唯一的要求。我将通过检查已创建值的列表来检查生成值中的冲突。我的请求中还有什么需要更正的吗?
-
或者我可以将原始输入(电子邮件)的一部分附加到生成的 id 以使其唯一吗?
-
@anataliocs 检查冲突的问题在于,在不抛出散列并重新开始的情况下做任何事情都为时已晚,并且需要记录原始值(除非有额外的输入限制) .它可以告诉那里是 一个问题,但可能不是所需要的.. 这种映射的最终目的 是什么?散列很棒,因为它仅在输入的情况下是可重复的。但是,如果在数据库中维护这样的映射(“输出”不需要[完全]依赖于输入),那么这是一个完全不同的球赛......
-
当然,12 个 [hex] 位仍然是一个“相当大的值”,因此,给定“相对少量”的输入,有一个非常好的机会分布良好的哈希(例如,SHA1 的前 12 位)将产生唯一的映射。但是,不存在这种情况的保证。增加目标空间大大降低了这种[随机]碰撞的可能性。比较 Mercucial/Hg(和吉特)。