web-dev-qa-db-ja.com

UUIDから一意の整数ID?

UUIDを一意の整数に変換する最も簡単な方法は何でしょうか?私はハッシュコードを使用しようとしましたが、ハッシュコードを使用すると常に一意になるとは限らないと人々は言っていますか?

それでは、最も簡単な方法は何ですか?ハッシュコードは一意ですか?

46

UUIDが128ビットであり、intが32ビットのみであるため、問題が発生します。衝突のリスクを受け入れ、それをより小さなスペースにファッジしようとする必要があります(hashCodeはおそらくそれを行うのに良い方法です)または代替を見つける(UUIDを直接使用します) 、BigIntegerへのマップ-理由を知らずに伝えるのは難しい)

32
Jeff Foster

どのようにユニークなアプリケーション全体の整数を持つことができますか?

再起動後も一意にする必要がある場合、またはアプリケーションがクラスタ化されている場合は、データベースシーケンスを使用できます。

実行時に一意にする必要がある場合は、静的な AtomicInteger を使用します。

EDIT(例の追加):

public class Sequence {

  private static final AtomicInteger counter = new AtomicInteger();

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

使用法:

int nextValue = Sequence.nextValue();

これはスレッドセーフです(異なるスレッドは常に個別の値を受け取り、値が「失われる」ことはありません)

11
pgras

いいえ、ハッシュコードは一意ではありません(一意にすることはできません)。 GUID/UUIDを使用すると、一意性を保証するために128ビットすべてが必要になるため、どのようにスケールダウンしても問題が発生します。 GUIDはグローバルに一意ですが、GUIDのサブストリングはそうではありません

正直なところ、連続した整数を使用して、GUIDを完全にスキップすることをお勧めします。何らかの理由でGUIDが必要な場合は、それらを使用し、整数を生成しようとしないでください。それら。

2
Joey

すべてのUUIDをシリアル番号に変換する必要がありました。最後に、次のアルゴリズムをテストして使用しました。

  1. ECMA多項式0xC96C5795D7870F42を使用してuuid(16バイト)のCRC64を取得します。 ISO多項式を使用しないでください。一部のUUID生成アルゴリズムで多くの衝突が発生する可能性があるためです。

  2. これでcrc64(8バイト)ができました。最初のNバイトを取得します(この例では5バイトで、intは4バイト、int64はすべてのバイトになります)

このメソッドをテストしたところ、数百万のUUIDでうまく機能しています。

追加の手順:5バイトの数値を基数36の数値に変換すると、最終的にSN:4YD3SOJBになります。

1
Anton Shelin

UUIDは16バイトの数値(128ビット)です。一意性を保持しながら、int(32ビット)に圧縮することはできません。

数学的に話された:296 UUIDは同じJava -int- sizeハッシュ値を共有します(これは...たくさんです;))

抜け道-現実のUUIDには静的な部分があることがよくあります。そのため、孤立したシナリオでは、real UUIDの一意の部分may 32ビット未満です。

1
Andreas_D