【问题标题】:How wide should be random numbers so it is virtually impossible that you repeat two of them?随机数应该有多宽,所以几乎不可能重复其中两个?
【发布时间】:2013-12-13 18:32:26
【问题描述】:

某些系统应该生成具有唯一 ID 的对象。该系统将在不同的计算机上运行,​​它们之间没有连接;但不会发生 ID 冲突。实现这一点的唯一方法是生成随机数。那些应该有多宽,这样你才能认为碰撞几乎不可能发生?

【问题讨论】:

  • 七十亿个案例中的 1 个是否被认为“几乎不可能”?如果你定义了你可以接受的概率,那么它应该可以给你答案。
  • JF Sebastian 是一个理想主义者,您正在寻找一个务实的答案。
  • The only way to implement this is generating random numbers — 你能解释一下为什么吗?例如,序号有什么问题?如果每台计算机都有一个唯一的 ID,那么可以将两者结合在一起形成一个全局唯一值。
  • @squeamishossifrage 这基本上就是 UUID/GUID 的作用。随机性与来自机器身份的恒定数据相结合,以确保唯一性。

标签: algorithm random language-agnostic


【解决方案1】:

这基本上是birthday problem的概括。

This probability table 可以帮助您确定需要多少位才能实现所需的概率 - 基于 p - 所需的概率,以及将被“散列”的 #elements (生成)。

【讨论】:

    【解决方案2】:

    在您提到的问题中:

    实现这一点的唯一方法是生成随机数

    不,这不是这样做的唯一方法。事实上,这是的方法之一。

    您自己现在正在使用一种众所周知且广泛使用的方法来执行此类操作:添加前缀(或后缀,无关紧要)。前缀被许多系统称为许多东西:以太网和 WiFi 将其称为供应商 ID。在 TCP/IP 中,它被称为子网(技术上称为“网络”)。

    这个想法很简单。例如,假设您想为您的全局 ID 使用 32 位数字。保留 8 位之类的东西来识别它在哪个系统上,其余的可以简单地是每个系统中的序列号。

    暂时从 IPv4 窃取语法。假设系统 1 的 id 为 1。系统 2 的 id 为 2。因此系统 1 的 id 将在 1.0.0.0 - 1.255.255.255 之间,系统 2 的 id 将在 2.0.0.0 - 2.255 之间。 255.255.

    这只是一个例子。没有什么会迫使您为系统 ID 浪费这么多位。事实上,IPv4 本身不再按字节边界组织。您可以改为使用 4 位作为系统 ID,使用 28 位作为单个 ID。如果您需要更多 id,也可以使用 64 位,或者使用 IPv6 路由并使用 128 位(在这种情况下,您绝对可以为系统 id 浪费一两个字节)。

    因为每个系统都无法生成由另一个系统生成的 id,所以在 id 溢出之前不会发生冲突。

    如果您需要 id 看起来“随机”,请使用散列算法。如果您的数据的固定大小低于散列大小,则可以保证良好的散列算法(例如 SHA1 和 CRC)永远不会发生冲突。例如,SHA1 是 160 位,因此如果您的 id 生成系统内部小于 160 位,那么 id 的 SHA1 哈希将永远不会发生冲突。需要注意的是您必须使用所有 160 位。旋转 SHA1 会导致冲突。对于 32 位 id,CRC32 非常适合,如果您想生成 64 位 id,还有 CRC64。

    【讨论】:

    • 您认为系统具有唯一 ID,但事实并非如此。
    • 为什么不是这样?
    【解决方案3】:

    Guids 使用 2^128,碰撞的可能性可以忽略不计

    【讨论】:

    • 为了避免货物崇拜编程,了解工具背后的一些概念可能很有用,而不是盲目地使用它们。特别是,了解碰撞概率以及在这种情况下如何计算它可能会有所帮助。
    • @J.F.Sebastian 他确实将我链接到包含我需要学习的所有内容的文章。只是忘记了这个特定的答案。
    猜你喜欢
    • 2011-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-14
    相关资源
    最近更新 更多