243

ドキュメントから2つの違いを理解しています。

uuid1()
ホストID、シーケンス番号、および現在の時刻からUUIDを生成します

uuid4()
ランダムなUUIDを生成します。

したがってuuid1、マシン/シーケンス/時間情報を使用してUUIDを生成します。それぞれを使用することの長所と短所は何ですか?

uuid1()マシン情報に基づいているため、プライバシーの問題が発生する可能性があることを私は知っています。どちらかを選ぶとき、これ以上微妙なことがあるのだろうか。uuid4()完全にランダムなUUIDなので、今使用しています。uuid1しかし、衝突のリスクを減らすために使用すべきかどうか疑問に思います。

基本的に、私は一方と他方を使用する際のベストプラクティスに関する人々のヒントを探しています。ありがとう!

4

6 に答える 6

282

uuid1()衝突が発生しないことが保証されています(同時に作成する衝突が多すぎないことを前提としています)。とコンピュータの間に接続がないことが重要な場合はuuid、MACアドレスを使用してコンピュータ間で一意にするため、使用しません。

100ns未満で214uuid1を超えるものを作成することで複製を作成できますが、これはほとんどのユースケースでは問題になりませ

uuid4()あなたが言ったように、ランダムなUUIDを生成します。衝突の可能性は本当に、本当に、本当に小さいです。十分に小さいので、心配する必要はありません。問題は、乱数ジェネレーターが悪いと、衝突が発生する可能性が高くなることです。

ボブ・アマンによるこの優れた答えは、それをうまく要約しています。(答え全体を読むことをお勧めします。)

率直に言って、悪意のあるアクターのない単一のアプリケーションスペースでは、1秒あたりかなりの数のUUIDを生成している場合でも、バージョン4のUUIDであっても、衝突が発生するずっと前に地球上のすべての生命の絶滅が発生します。

于 2009-11-23T20:05:41.577 に答える
37

uuid1()UUIDが別々のマシンで生成されるuuid4()場合、たとえば、スケーリングの目的で複数のオンライントランザクションが複数のマシンで処理される場合など、検討する場合の1つの例があります。

このような状況では、たとえば、疑似乱数ジェネレーターの初期化方法の選択が不十分なために衝突が発生するリスクがあります。また、生成されるUUIDの数が増える可能性があるため、IDが重複する可能性が高くなります。

その場合のもう1つの興味深い点はuuid1()、各GUIDが最初に生成されたマシンが暗黙的に記録されることです(UUIDの「ノード」部分に)。これと時間情報は、デバッグの場合にのみ役立つ場合があります。

于 2009-11-23T20:18:20.850 に答える
33

私のチームは、データベースアップグレードスクリプトにUUID1を使用する際に問題が発生し、数分以内に最大120kのUUIDを生成しました。UUIDの衝突により、主キー制約に違反しました。

数百台のサーバーをアップグレードしましたが、Amazon EC2インスタンスで、この問題が数回発生しました。クロックの解像度が低く、UUID4に切り替えることで解決したと思います。

于 2015-12-21T08:51:22.250 に答える
7

を使用する際の注意点の1つuuid1は、(パラメーターを指定せずにclock_seq)デフォルトの呼び出しを使用すると、衝突が発生する可能性があることです。ランダム性は14ビットしかありません(100ns以内に18エントリを生成すると、衝突の可能性は約1%になります。誕生日のパラドックス/攻撃)。ほとんどのユースケースでこの問題が発生することはありませんが、クロック解像度の低い仮想マシンでは問題が発生します。

于 2014-06-17T18:49:50.797 に答える
6

おそらく言及されていないのは、地域の問題です。

MACアドレスまたは時間ベースの順序付け(UUID1)を使用すると、ランダムに分散された番号(UUID4)よりも数値を並べ替える作業が少なくなるため、データベースのパフォーマンスを向上させることができます(ここを参照)。

2番目の関連する問題は、元のデータが失われたり、明示的に保存されていなくても、UUID1の使用がデバッグに役立つ可能性があることです(これは明らかにOPによって言及されたプライバシーの問題と矛盾します)。

于 2017-04-13T16:46:30.617 に答える
3

受け入れられた回答に加えて、場合によっては役立つ3番目のオプションがあります。

ランダムMACを使用したv1( "v1mc")

ランダムなブロードキャストMACアドレスを使用してv1UUIDを意図的に生成することにより、v1とv4のハイブリッドを作成できます(これはv1仕様で許可されています)。結果のv1UUIDは(通常のv1のように)時間に依存しますが、すべてのホスト固有の情報(v4のように)を欠いています。また、衝突耐性の点でv4にはるかに近いです。v1mc=60ビットの時間+61のランダムビット=121の一意のビット。v4=122ランダムビット。

私が最初にこれに遭遇したのは、Postgresのuuid_generate_v1mc()関数でした。それ以来、次のPythonに相当するものを使用しました。

from os import urandom
from uuid import uuid1
_int_from_bytes = int.from_bytes  # py3 only

def uuid1mc():
    # NOTE: The constant here is required by the UUIDv1 spec...
    return uuid1(_int_from_bytes(urandom(6), "big") | 0x010000000000)

(注:UUIDオブジェクトを直接作成するより長い+より高速なバージョンがあります。必要に応じて投稿できます)


大量の呼び出し/秒の場合、これはシステムのランダム性を使い果たす可能性があります。代わりにstdlibモジュールを使用することもできます(おそらくより高速になります)。randomただし、注意してください。攻撃者がRNGの状態を判断し、将来のUUIDを部分的に予測できるようになるまでには、数百のUUIDしか必要ありません。

import random
from uuid import uuid1

def uuid1mc_insecure():
    return uuid1(random.getrandbits(48) | 0x010000000000)
于 2017-08-18T18:09:08.277 に答える