【问题标题】:Generating integer within range from unique string in ruby从ruby中的唯一字符串生成范围内的整数
【发布时间】:2012-03-18 03:37:30
【问题描述】:

我有一个代码应该从客户端获取唯一字符串(例如,“d86c52ec8b7e8a2ea315109627888fe6228d”)并返回大于 2200000000 且小于 5800000000 的整数。重要的是,生成的 int 不是随机的,它应该是一对一的唯一的字符串。在不使用 DB 的情况下生成它的最佳方法是什么?

现在看起来像这样:

did = "d86c52ec8b7e8a2ea315109627888fe6228d"
min_cid = 2200000000
max_cid = 5800000000
cid = did.hash.abs.to_s.split.last(10).to_s.to_i
if cid < min_cid
  cid += min_cid
else
  while cid > max_cid
    cid -= 1000000000
  end
end

【问题讨论】:

  • 没有办法保证小于值空间的键空间中的数字的唯一性。您可以期望的最好结果是碰撞的机会相对较小。此外,您的算法存在一些缺陷,因为您通过将 220000000 添加到低于您的百万的哈希值中引入了额外的冲突可能性,这将与映射到该新值的东西发生冲突。
  • 好的,为特定设备生成最大的特定数字集很重要,它不会随时间改变。碰撞不是什么大问题,但碰撞越少越好。

标签: ruby string random integer


【解决方案1】:

这就是问题所在 - 您的数字范围只有 3.6x10^9 个可能的值,而您的示例唯一字符串(看起来像一个 36 位的十六进制整数)有 16^32 个可能的值(即 很多时间>更多)。所以当你的字符串映射到你的整数范围时会有冲突

映射函数本身可以非常简单,我会执行以下操作(另外,如果性能变得至关重要,请考虑仅使用输入字符串的一部分进行整数转换,例如前七位):

def my_hash(str, min, max)
  range = (max - min).abs
  (str.to_i(16) % range) + min
end

my_hash(did, min_cid, max_cid) # => 2461595789

[编辑]如果您使用的是 Ruby 1.8,并且您的调整范围可以表示为 Fixnum,只需使用输入字符串对象的 hash value,而不是将其解析为大整数。请注意,此策略在 Ruby 1.9 中可能不安全(根据 @DataWraith 的评论),因为对象哈希值可能在解释器的调用之间随机化,因此当您重新启动应用程序时,您不会为相同的输入字符串获得相同的哈希值:

def hash_range(obj, min, max)
  (obj.hash % (max-min).abs) + [min, max].min
end

hash_range(did, min_cid, max_cid) # => 3886226395

当然,您还必须决定如何处理碰撞。您可能必须保留一组映射到相同值的输入字符串,并在通过映射值查找时决定如何解决冲突。

【讨论】:

  • @Alexey Krasnoperov - Ruby 有一个内置的结构来处理这种冲突。 maerics 正在用他的方法名称轻轻地引导你。
  • 感谢您的回答,我使用了第二种变体,效果很好。
  • 请注意,在重新启动应用程序后(至少在 1.9 中),#hash 不会为相同的输入给出相同的结果,因为 #hash 是随机的,以防止某一类 DoS 攻击。
  • @AlexeyKrasnoperov:哎呀!请注意 DataWraith 的评论。我只在不随机化的 ruby​​ 1.8 上进行了测试,因此请确保您的 ruby​​ 版本在调用解释器之间对相同的字符串使用相同的哈希码。我会根据这些信息更新我的答案。
【解决方案2】:

您可以生成一个 32 位 CRC,删除一位,然后将结果添加到 2.2M。这为您提供了 4.3M 的最大值。
或者,您可以使用 CRC 的所有 32 位,但是当结果太大时,将零附加到输入字符串并重新计算,重复直到获得范围内的值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-24
    • 2018-12-17
    • 2014-03-12
    • 1970-01-01
    相关资源
    最近更新 更多