uuid.uuid1() を使用する必要がある場合と、Pythonのuuid.uuid4()?
質問
両者の違いは理解できました ドキュメント。
uuid1()
:
ホストID、シーケンス番号、および現在時刻からUUIDを生成します。
uuid4()
:
ランダムな UUID を生成します。
それで uuid1
マシン/シーケンス/時間情報を使用して UUID を生成します。それぞれを使用する場合の長所と短所は何ですか?
知っている uuid1()
マシン情報に基づいているため、プライバシーの懸念がある可能性があります。どちらかを選択するときに、さらに微妙な点があるのではないかと思います。ただ使っているだけです uuid4()
現時点では、これは完全にランダムな UUID であるためです。でも使ったほうがいいのかな uuid1
衝突の危険を軽減します。
基本的に、私は 1 つと 2 つの方法を使用する際のベスト プラクティスに関する人々のヒントを探しています。もう一方。ありがとう!
解決
uuid1()
衝突が発生しないことが保証されています (同時に衝突をあまり多く発生させないという前提の下で)。間に関連性がないことが重要な場合は使用しません。 uuid
MAC アドレスは、複数のコンピュータ間で一意になるように使用されるため、コンピュータでも同様です。
2 つ以上作成すると複製を作成できます14 uuid1 は 100ns 未満ですが、これはほとんどの使用例では問題になりません。
uuid4()
あなたが言ったように、ランダムな UUID を生成します。衝突の可能性は本当に、本当に、 本当に 小さい。十分に小さいので、心配する必要はありません。問題は、乱数ジェネレーターが不良であると、衝突が発生する可能性が高くなるということです。
ボブ・アマンによるこの素晴らしい回答 うまくまとめています。(回答全体を読むことをお勧めします。)
率直に言って、悪意のある俳優のいない単一のアプリケーションスペースでは、地球上のすべての生命の絶滅は、バージョン4 UUIDでさえ衝突するずっと前に発生します。
他のヒント
検討できる一例として、 uuid1()
それよりも uuid4()
は UUID が別のマシンで生成される場合, たとえば、スケーリング目的で複数のオンライン トランザクションが複数のマシンで処理される場合などです。
このような状況では、たとえば、擬似乱数ジェネレーターの初期化方法の選択が不適切なために衝突が発生するリスクがあり、また生成される UUID の数が潜在的に多くなるため、重複した ID が作成される可能性が高くなります。
もう一つの興味は、 uuid1()
, この場合、各 GUID が最初に生成されたマシンが暗黙的に (UUID の「ノード」部分に) 記録されます。これと時間情報は、デバッグにのみ役立つ場合があります。
私のチームは、ちょうど私たちは数分以内に〜120K UUIDを生成したデータベースのアップグレードスクリプトのUUID1を使用してトラブルに走りました。 UUID衝突が主キー制約の違反につながっています。
私たちは、サーバの100Sをアップグレードしましたが、お求めはAmazon EC2インスタンス上で、私たちはこの問題に数回走りました。私は貧しいクロックの分解能を疑うとUUID4に切り替えることは私たちのためにそれを解決します。
一つuuid1
を使用しているときに(clock_seq
パラメータを与えることなく)デフォルトのコールを使用している場合、あなたは衝突に実行しているのチャンスを持っている:あなたがランダムの唯一の14ビット(100nsの内の18個のエントリを生成するには、あなたにおよそ1%を与えてい衝突を参照してください誕生日パラドックス/攻撃のチャンス)。問題は、ほとんどのユースケースで発生することはありませんが、貧しいクロックの分解能を持つ仮想マシン上で、それはあなたを噛まされます。
おそらく、言及されていない何かが地域のことです。
それはより近く、一緒にランダムに分散したものよりもソート番号に以下の作業がありますので、AのMACアドレスまたは時間ベースの順序(UUID1)は、データベースのパフォーマンスを高め余裕がある(UUID4は)(<参照のhref = "のhttp:// WWW。 をここinformit.com/articles/article.aspx?p=25862" のrel = "nofollowをnoreferrer">)。
第2の関連の問題は、(これはプライバシーの問題と競合して明らかであるが、OP言及)UUID1を使用して原点データが失われたり、明示的に格納されていない場合であっても、デバッグに有用であり得るということである。
受け入れ答えに加えて、いくつかのケースで役立つことができ番目のオプションがあります:
v1のランダムとMAC( "v1mc")
あなたは故意に(これはv1の仕様によって許可されている)ランダムブロードキャストMACアドレスとV1のUUIDを生成することにより、V1&V4間の雑種を作ることができます。得られたV1 UUIDは時間(正規V1等)に依存するが、(V4のような)すべてのホスト固有の情報を欠いています。それの衝突抵抗に非常に近いV4にも次のとおりv1mc時間+ 61 = 60ビットランダムビット= 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)