2011-04-06 609 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