【问题标题】:UUID to unique integer id?UUID 到唯一的整数 id?
【发布时间】:2011-07-30 15:04:28
【问题描述】:

我想知道将 UUID 转换为唯一整数的最简单方法是什么?我尝试过使用哈希码,但人们告诉我,如果我使用哈希码,它并不总是唯一的?

那么最简单的方法是什么?哈希码是否唯一?

【问题讨论】:

  • 不,它不是 - 根据定义。另外,如果它是唯一的,那么为什么会有人需要 UUID?
  • 定义唯一。在全球范围内,还是仅在您的应用程序中,或一些代码?
  • 只是根据一些愚蠢的规范,我需要一个应用程序唯一整数,我想使用 UUID 类,但事实证明我无法缩小它。
  • 如果你问真正的问题会更容易:我怎样才能有一个应用程序唯一的整数?我可以将 UUID 转换为它吗?然后我们可以回答您的问题,而不仅仅是告诉您不能为此目的使用 UUID...

标签: java uuid


【解决方案1】:

您可以将 uuid 转换为 BigInteger 并保持其唯一性。

              BigInteger  big = new BigInteger(uuid, 16);

【讨论】:

    【解决方案2】:

    我们需要将所有 UUID 转换为序列号。最后,我们测试并使用了下一个算法:

    1. 使用 ECMA 多项式获取 uuid(16 字节)的 CRC64 0xC96C5795D7870F42。不要使用 ISO 多项式,因为它可能导致 一些 UUID 生成算法有很多冲突。

    2. 现在我们有了 crc64(8 字节)。取前 N 个字节(在我们的例子中 5 在你的它将是 int 的 4 个字节和 int64 的所有字节)

    我们测试了这种方法,它适用于数百万个 UUID。

    我们的附加步骤:将 5 个字节的数字转换为以 36 为底的数字,最后我们得到 SN:4YD3SOJB。

    【讨论】:

    • 太棒了!但是有没有使用特殊多项式的 CRC64 库?我正在使用 Python,并且有一个 CRC64ISO,我猜这不是你的意思。事件一个 C 库很好,因为我可以使用 ffi 来调用它。
    【解决方案3】:

    回答我如何才能拥有一个独特的应用程序范围的整数:

    如果即使在重新启动后它也需要是唯一的,或者如果您的应用程序是集群的,您可以使用数据库序列。

    如果它只需要在运行时唯一,请使用静态 AtomicInteger

    编辑(添加示例):

    public class Sequence {
    
      private static final AtomicInteger counter = new AtomicInteger();
    
      public static int nextValue() {
        return counter.getAndIncrement();
      }
    }
    

    用法:

    int nextValue = Sequence.nextValue();
    

    这是线程安全的(不同的线程将始终接收不同的值,并且不会“丢失”任何值)

    【讨论】:

    • 你能举个例子说明如何使用 AtomicInteger 吗?
    • 用法应该被编辑;显示“Counter.nextValue();”,但该类名为“Sequence”
    • 这个用法只能被单个jvm使用,集群(多个jvm)不能使用这个选项。
    • 如果生成的不同值超出 int 范围会怎样?这会发生吗?
    【解决方案4】:

    不,哈希码不是(也不能是)唯一的。 GUID/UUID 的问题是您需要所有 128 位来保证唯一性,因此以任何方式缩小它都会产生问题,例如GUIDs are globally unique, but substrings of GUIDs aren't.

    老实说,我认为您最好只使用顺序整数并完全跳过 GUID。如果您出于任何原因需要 GUID,请使用它们,不要尝试从它们生成整数。

    【讨论】:

    • 评论:1) 哈希码可能是唯一的。你不知道。 Don't rely on it though。 2)您无法保证 UUID 的唯一性。只是很有可能永远不会发生碰撞。 3)即使您确实“以任何方式缩小规模”,也不一定会产生任何问题。是的,您增加了碰撞的风险,并且您需要了解违反 UUID 标准的后果,但在某些情况下这可能完全没问题。 4) 链接失效了。
    【解决方案5】:

    UUID 是一个 16 字节的数字(128 位)。您不能将其压缩成int(32 位)同时保留它的唯一性。

    从数学上讲:296 个 UUID 将共享相同的 Java-int-size 哈希值(这是...很多;))

    出路 - 一些现实生活中的 UUID 通常具有相当静态的部分。因此,在孤立的场景中,UUID 的真实唯一部分可能小于 32 位。

    【讨论】:

      【解决方案6】:

      你会遇到问题,因为 UUID 是 128 位,而 int 只有 32 位。您要么必须接受碰撞的风险,并尝试将其捏造到更小的空间(hashCode 可能是这样做的好方法),要么找到替代方案(直接使用UUID,映射到@987654323 @ - 不知道为什么很难说)

      【讨论】:

        猜你喜欢
        • 2019-01-27
        • 1970-01-01
        • 1970-01-01
        • 2014-02-03
        • 2021-07-29
        • 2017-07-29
        • 2021-12-14
        • 2015-03-21
        • 2011-11-03
        相关资源
        最近更新 更多