2011-04-06 606 views
31

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

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

+0

不,它不是 - 根据定义。另外,如果它是唯一的,那么为什么有人需要UUID? – Ingo 2011-04-06 08:35:34

+0

定义独特。在全球范围内,还是仅仅在您的应用程序或一些代码? – 2011-04-06 08:36:18

+0

它只是通过一些愚蠢的规范我需要一个应用程序唯一的整数,我想利用UUID类,但事实证明我不能缩小它。 – 2011-04-06 08:58:45

回答

24

由于UUID是128位而int只有32位,所以会出现问题。您必须接受碰撞的风险,并尝试将其调整到更小的空间(hashCode可能是一种很好的方法),或者找到替代方案(直接使用UUID,映射到BigInteger--难以分辨知道为什么)

+3

hashCode是我所需要的。对于我的情况,我需要将一个int作为NotificationId传递给Android的NotificationManager。我可以容忍这些通知的碰撞。 – tmin 2014-08-05 00:20:44

2

不,散列码不是(也不可以)是唯一的。具有GUID/UUID的事情是,您需要全部128位来保证唯一性,因此以任何方式缩小它都会产生问题,请参阅参考资料。 GUIDs are globally unique, but substrings of GUIDs aren't

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

+3

评论:1)哈希码可能是唯一的。你不知道。 [不要依靠它](http://security.stackexchange.com/a/52881/94827)。 2)您无法保证UUID唯一性。从未发生碰撞的可能性很大。 3)即使你“以任何方式缩小了”,你也不一定会产生任何问题。是的,你增加了碰撞的风险,你需要知道打破UUID标准的后果,但在某些情况下这可能会非常好。 4)链接已经死亡。 – Zero3 2016-01-11 09:26:34

1

UUID是一个16字节数(128位)。你不能把它压缩成一个int(32位),同时保持它的唯一性。

数学上所说:2点96点的UUID将共享同一个Java的int -size散列值(这是...很多;))

出路 - 一些现实生活中的UUID往往有一个相当静态部分。因此,在孤立的情况下,UUID 的唯一部分可能小于32位。

9

接听怎样才可以有一个独特的应用广泛整数:

如果它必须是唯一的,即使重新启动后,或者如果你的应用程序是群集你可以使用一个数据库序列。

如果只是在运行期间需要唯一,请使用静态的AtomicInteger

编辑(添加实施例):

public class Sequence { 

    private static final AtomicInteger counter = new AtomicInteger(); 

    public static int nextValue() { 
    return counter.getAndIncrement(); 
    } 
} 

用法:

int nextValue = Sequence.nextValue(); 

这是线程安全(不同的线程将始终接收不同的值,也没有值将 “丢失”)

+0

你可以给我一个如何使用AtomicInteger的例子吗? – 2011-04-06 11:29:03

+1

使用应该被编辑;显示“Counter.nextValue();”,但该类名为“序列” – 2016-07-20 17:57:49

+0

此用法仅适用于单个jvm,群集(多个jvms)无法使用此选项。 – 2017-05-23 07:39:01