【问题标题】:One way function to hash a variable length string into a 12 digit number in Groovy在 Groovy 中将可变长度字符串散列为 12 位数字的一种方法函数
【发布时间】:2012-05-17 01:38:49
【问题描述】:

我有由字母、数字和特殊字符(电子邮件地址)组成的唯一可变长度字符串列表。列表中的每个电子邮件地址都是唯一的。

我需要一个单向散列函数(我不需要能够从生成的数字中检索原始值),它将用盐对字符串进行散列并生成一个 12 位数字。

我想确保唯一性,因此我将检查先前生成的值列表以检测冲突,然后在发生冲突时生成一个新数字。可预测性不是问题。

理想情况下,我希望这个函数用 Groovy 编写,但 Java 也可以。

【问题讨论】:

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

标签: java random groovy hash


【解决方案1】:

我需要保证每个生成的数字都是唯一的。

这显然是个问题。可能的输入字符串多于可能的输出值。特别是,每个可能的输出值(12 位字符串)都是可能的输入值。因此,如果所有这些都获得唯一的输出值,则不可能为任何 other 输入值留下任何输出值。

当然,您总是可以记录您遇到的每个电子邮件地址(因此第一个以 000000000000 结尾,第二个以 000000000001 等结尾),但这是一个存储问题,而不是散列本身。如果没有后备存储,您将无法从输入获得输出。

【讨论】:

  • 输出会有冲突问题。
  • @BhavikAmbani:完全正确 - 当可能的输入多于输出时,您无法生成唯一数字。
  • @OliCharlesworth:如果你事先知道名单,是的。如果函数必须只接受一个字符串,没有其他参考数据或存储,那么你就有麻烦了......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-05
  • 2017-12-26
  • 2016-10-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多