JavaにおけるUUIDの手引き

JavaのUUIDのガイド

1. 概要

UUID(Universally Unique Identifier)は、GUID(Globally Unique Identifier)とも呼ばれ、a 128-bit long value that is unique for all practical purposesを表します。 UUIDの標準表現では、16進数(オクテット)が使用されます。

123e4567-e89b-12d3-a456-556642440000

UUIDは、16進数(各4文字)と、そのlength equal to 36 charactersを構成する4つの「-」記号で構成されます。

Nil UUIDは、すべてのビットがゼロに設定される特別な形式のUUIDです。

この記事では、JavaのUUIDクラスについて説明します。

参考文献:

CharSequence vs. Javaの文字列

CharSequenceとStringの違いを学びます。

Javaでパスワードを操作するための文字列上のUse char[配列?]

パスワードの保存に文字列を使用しない理由をいくつか調べ、代わりにchar []配列を使用してください。

Java文字列プールのガイド

JVMがJava文字列プールの文字列ストレージに割り当てられるメモリ量を最適化する方法を学びます。

2. 構造

UUIDの例を見てみましょう。

123e4567-e89b-42d3-a456-556642440000
xxxxxxxx-xxxx-Bxxx-Axxx-xxxxxxxxxxxx

Aは、UUIDのレイアウトを決定するバリアントを表します。 UUIDの他のすべてのビットは、バリアントフィールドのビットの設定に依存します。 バリアントは、Aの3つの最上位ビットによって決定されます。

  MSB1    MSB2    MSB3
   0       X       X     reserved (0)
   1       0       X     current variant (2)
   1       1       0     reserved for Microsoft (6)
   1       1       1     reserved for future (7)

上記のUUIDのAの値は「a」です。 'a'(= 10xx)に相当するバイナリは、バリアントを2として示します。 Bはバージョンを表します。 上記のUUID(Bの値)のバージョンは4です。

JavaはUUID:__のバリアントとバージョンを取得するためのメソッドを提供します

UUID uuid = UUID.randomUUID();
int variant = uuid.variant();
int version = uuid.version();

これらは、バリアント2 UUIDの5つの異なるバージョンです:時間ベース(UUIDv1)、DCEセキュリティ(UUIDv2)、名前ベース(UUIDv3およびUUIDv5)、ランダム(UUIDv4)。

Javaは、v3およびv4の実装を提供しますが、任意のタイプのUUIDを生成するためのconstructorも提供します。

UUID uuid = new UUID(long mostSigBits, long leastSigBits);

2.1. バージョン3&5

UUIDは、名前空間と名前のハッシュを使用して生成されます。 名前空間識別子は、ドメインネームシステム(DNS)、オブジェクト識別子(OID)、URLなどのUUIDです。

UUID = hash(NAMESPACE_IDENTIFIER + NAME)

UUIDv3とUUIDv5の唯一の違いは、ハッシュアルゴリズムです。v3はMD5(128ビット)を使用し、v5はSHA-1(160ビット)を使用します。

簡単に言えば、結果のハッシュを128ビットに切り捨ててから、バージョンの4ビットとバリアントの2ビットを置き換えます。

タイプ3 UUIDを生成しましょう:

String source = namespace + name;
byte[] bytes = source.getBytes("UTF-8");
UUID uuid = UUID.nameUUIDFromBytes(bytes);

Javaは、タイプ5の実装を提供しません。 UUIDv5のソースコードrepositoryを確認してください。

2.2. バージョン4

UUID v4実装では、乱数をソースとして使用します。 Javaの実装はSecureRandomです。これは、予測できない値をシードとして使用して乱数を生成し、衝突の可能性を減らします。

バージョン4 UUIDを生成しましょう:

UUID uuid = UUID.randomUUID();

「SHA-256」とランダムなUUIDを使用して一意のキーを生成しましょう。

MessageDigest salt = MessageDigest.getInstance("SHA-256");
salt.update(UUID.randomUUID().toString().getBytes("UTF-8"));
String digest = bytesToHex(salt.digest());

3. 結論

UUIDv3とUUIDv5の両方には、異なるシステムが同じ名前空間と名前を使用して同じUUIDを生成できるという素晴らしいプロパティがあります。 これらは基本的に階層UUIDの作成に使用されます。

ハッシュ関数MD5とSHA1の両方が壊れているため、v5を使用することをお勧めします。 単純なUUIDの生成だけが必要な場合、一般的なユースケースではタイプ4で問題ありません。

そして、いつものように、実装のソースコードは利用可能なover on Githubです。