man
ページを読みましたが、name
とnamespace
の目的がわかりません。
バージョン3およびバージョン5 UUIDの場合、追加のコマンドライン引数の名前空間と名前を指定する必要があります。名前空間は、文字列表現のUUIDまたは内部で事前定義された名前空間UUIDの識別子のいずれかです(現在知られているのは「ns:DNS」、「ns:URL」、「ns:OID」、および「ns:X500」です)。名前は任意の長さの文字列です。
名前空間:
名前空間は、文字列表現のUUIDまたは
生成されたUUID v5と関連してどこかに(UUID v4)保存する必要があるということですか?どちらの場合でも、なぜこれは自動的に行われないのですか?
名前は任意の長さの文字列です。
name
完全にランダムな文字列?その目的は何ですか? UUID v5からデコードできますか?
名前と名前空間を使用して、(おそらく)一意のUUIDの階層を作成できます。
大まかに言って、タイプ3またはタイプ5 UUIDは、名前空間識別子と名前をハッシュすることで生成されます。タイプ3 UUIDはMD5を使用し、タイプ5 UUIDはSHA1を使用します。 128ビットのみが使用可能であり、5ビットを使用してタイプを指定するため、すべてのハッシュビットがUUIDに含まれません。 (MD5は暗号が破られていると見なされ、SHA1は最後のレッグにあるため、「非常に安全」である必要があるデータを検証するためにこれを使用しないでください)。ただし、階層名を確率的に一意の128ビット値にマッピングし、潜在的に階層ハッシュまたはMACのように動作する、反復可能/検証可能な「ハッシュ」関数を作成する方法を提供します。
(キー、値)ストアがあるが、1つの名前空間しかサポートしていないとします。タイプ3またはタイプ5 UUIDを使用して、多数の個別の論理ネームスペースを生成できます。最初に、各ネームスペースのルートUUIDを作成します。どこかに隠しておく限り、タイプ1(ホスト+タイムスタンプ)またはタイプ4(ランダム)UUIDにすることができます。または、ルート用にoneランダムUUIDを作成(またはnull
UUID:00000000-0000-0000-0000-000000000000
をルートとして使用)してから、 「uuid -v5 $ROOTUUID $NAMESPACENAME
」を使用して、各ネームスペースに再現可能なUUIDを作成します。 「uuid -v5 $NAMESPACEUUID $KEY
」を使用して、名前空間内のキーに一意のUUIDを作成できるようになりました。これらのUUIDは、衝突を回避する可能性が高い単一のキー値ストアにスローできます。このプロセスは再帰的に繰り返すことができます。たとえば、UUIDキーに関連付けられた「値」がバケット、コンテナ、ディレクトリなどの論理的な「名前空間」を表す場合、そのUUIDを使用して、より階層的に生成できますUUID。
生成されたタイプ3またはタイプ5 UUIDは、名前空間IDと名前空間内の名前(キー)の(部分的な)ハッシュを保持します。メッセージMACがエンコード元のメッセージの内容を保持するのと同じように、名前空間UUIDを保持することはありません。名前は、uuidアルゴリズムの観点から「任意の」(オクテット)文字列です。ただし、その意味はアプリケーションによって異なります。論理ディレクトリ内のファイル名、オブジェクトストア内のオブジェクトIDなどです。
これは、適度に多数の名前空間とキーに対してはうまく機能しますが、非常に高い確率で一意である非常に多くのキーを目指す場合は、最終的にSteamを使い果たします。誕生日問題(別名バースデーパラドックス)のWikipediaエントリには、さまざまな数のキーとテーブルサイズの少なくとも1つの衝突の確率を与えるテーブルが含まれています。 128ビットの場合、この方法で260億個のキーをハッシュするとp=10^-18
(ごくわずか)の衝突の可能性がありますが、26兆個のキーは、p=10^-12
(1兆分の1 )、および26*10^15
キーのハッシュにより、p=10^-6
(100万分の1)への少なくとも1つの衝突の確率が高くなります。 UUIDタイプをエンコードする5ビットを調整すると、それはいくぶん速くなります。そのため、1兆個のキーは、1コリジョンの可能性が1兆分の1程度です。
確率表については、 http://en.wikipedia.org/wiki/Birthday_problem#Probability_table を参照してください。
UUIDエンコードの詳細については、 http://www.ietf.org/rfc/rfc4122.txt を参照してください。
タイプ3とタイプ5のUUIDは、hashをUUIDに詰め込む技術にすぎません。
SHA1ハッシュは160ビット(20バイト)を出力します。ハッシュの結果はUUIDに変換されます。 SHA1の20バイトから:
SHA1 Digest: 74738ff5 5367 e958 9aee 98fffdcd1876 94028007
UUID (v5): 74738ff5-5367-5958-9aee-98fffdcd1876
^_low nibble is set to 5 to indicate type 5
^_first two bits set to 1 and 0, respectively
(「9」の最初の2ビットは、それぞれ1と0であるため、効果はありません)。
おそらく、私がハッシュすることになっているのは何だろうと思っているでしょう。基本的に、次の連結をハッシュします。
sha1([NamespaceUUID]+[AnyString]);
名前の競合を防ぐために、いわゆるnamespaceを文字列の前に付けます。
ID RFC は、4つのネームスペースを事前定義します。
NameSpace_DNS
:{6ba7b810-9dad-11d1-80b4-00c04fd430c8}NameSpace_URL
:{6ba7b811-9dad-11d1-80b4-00c04fd430c8}NameSpace_OID
:{6ba7b812-9dad-11d1-80b4-00c04fd430c8}NameSpace_X500
:{6ba7b814-9dad-11d1-80b4-00c04fd430c8}だから、一緒にハッシュすることができます:
StackOverflowDnsUUID = sha1(Namespace_DNS + "stackoverflow.com");
StackOverflowUrlUUID = sha1(Namespace_URL + "stackoverflow.com");
RFCでは、次の方法を定義しています。
基本的な要点は、最初の128ビットのみを取得し、5
をtypeレコードに挿入し、clock_seq_hi_and_reserved
セクションの最初の2ビットを1と0に設定することです。それぞれ。
いわゆるNameを生成する関数ができたので、関数を(擬似コードで)持つことができます。
UUID NameToUUID(UUID NamespaceUUID, String Name)
{
byte[] hash = sha1(NamespaceUUID.ToBytes() + Name.ToBytes());
UUID result;
Copy(hash, result, 16);
result[6] &= 0x0F;
result[6] |= 0x50;
result[8] &= 0x3F;
result[8] |= 0x80;
return result;
}
(システムのエンディアンネスが上記バイトのインデックスに影響する可能性があることに注意してください)
電話をかけることができます:
uuid = NameToUUID(Namespace_DNS, 'www.stackoverflow.com');
uuid = NameToUUID(Namespace_DNS, 'www.google.com');
uuid = NameToUUID(Namespace_URL, 'http://www.stackoverflow.com');
uuid = NameToUUID(Namespace_URL, 'http://www.google.com/search&q=rfc+4112');
uuid = NameToUUID(Namespace_URL, 'http://stackoverflow.com/questions/5515880/test-vectors-for-uuid-version-5-converting-hash-into-guid-algorithm');
バージョン3およびバージョン5 UUIDの場合、追加のコマンドライン引数のネームスペースと名前を指定する必要があります。名前空間は、文字列表現のUUIDまたは内部で事前定義された名前空間UUIDの識別子のいずれかです(現在知られているのは「ns:DNS」、「ns:URL」、「ns:OID」、および「ns:X500」です)。名前は任意の長さの文字列です。
namespaceは、好きなUUIDです。事前に定義されたもののいずれか、または独自のものを作成することができます、例えば:
UUID Namespace_RectalForeignExtractedObject = '4d79546f-6e67-7565-496e-486572417373'
名前は任意の長さの文字列です。
名前は、名前空間に追加し、ハッシュし、UUIDに詰め込むだけのテキストです。
uuid = NameToUUID('8e884ace-bee4-11e4-8dfc-aa07a5b093db', 'screwdriver');
uuid = NameToUUID('8e884ace-bee4-11e4-8dfc-aa07a5b093db', 'toothbrush');
uuid = NameToUUID('8e884ace-bee4-11e4-8dfc-aa07a5b093db', 'broomstick');
uuid = NameToUUID('8e884ace-bee4-11e4-8dfc-aa07a5b093db', 'orange');
uuid = NameToUUID('8e884ace-bee4-11e4-8dfc-aa07a5b093db', 'axe handle');
uuid = NameToUUID('8e884ace-bee4-11e4-8dfc-aa07a5b093db', 'impulse body spray');
uuid = NameToUUID('8e884ace-bee4-11e4-8dfc-aa07a5b093db', 'iPod Touch');
注:パブリックドメインにリリースされたコード。帰属は必要ありません。
名前は、あるネームスペース内で一意の識別子にすぎません。問題は、ネームスペースが非常に小さく、ある名前が他の名前と衝突することが多いことです。たとえば、私の車のナンバープレート番号(名前)は州のDMVの名前空間内で一意ですが、おそらく世界では一意ではありません。他の状態DMVは、独自の名前空間で同じ名前を使用している場合があります。ちなみに、他の誰かが電話番号(名前)を持っている可能性もあります。これは、さらに別の名前空間などであるためです。
UUIDは単一の名前空間に生息していると見なすことができるため、everything;に一意の名前を付けることができます。それが「ユニバーサル」の意味です。しかし、他の名前空間にある既存の名前をどのようにUUIDにマッピングしますか?
明らかな解決策の1つは、すべてのアイテムのUUID(V1またはV4)を生成して、それぞれの名前空間の古い名前を置き換えることです。欠点は、それらがはるかに大きく、データセットのコピーを持っているすべての人にすべての新しい名前を伝えなければならないこと、すべてのAPIを更新する必要があることなどです。とにかく、これはすべてのアイテムがtwoの名前を持っていることを意味するので、物事を良くしたり悪くしたりしましたか?
これがV3/V5の出番です。UUIDlookはV4と同じくらいランダムですが、実際には決定論的です。名前空間に対して正しいUUIDを持っている人は誰でも独立してその名前空間内の任意の名前に対して同じUUIDを生成できます。誰でも必要に応じてその場で作成できるため、公開する必要も事前に生成する必要もありません!
DNS名とURLは非常に一般的に使用される名前空間であるため、それらの標準UUIDが公開されました。 ASN.1 OIDとX.500名はそれほど一般的ではありませんが、標準化団体はそれらを愛しているので、標準の名前空間UUIDも公開しました。
他のすべてのネームスペースについては、独自のネームスペースUUID(V1またはV4)を生成し、それを必要とする人に伝える必要があります。複数のネームスペースがある場合、それぞれのUUIDを公開することは明らかに理想的ではありません。
これが階層の出番です。「ベース」UUID(タイプは問わない)を1つ作成し、それを他の名前空間に名前を付けるための名前空間として使用します。そうすれば、ベースUUIDを公開するだけで(または明らかなUUIDを使用すれば)、誰もが残りを計算できます。
たとえば、StackOverflowのUUIDをいくつか作成したいと考えています。 DNS名前空間内に明白な名前があるため、ベースは明白です。
uuid ns_dns = '6ba7b810-9dad-11d1-80b4-00c04fd430c8';
uuid ns_base = uuidv5(ns_dns, 'stackoverflow.com');
StackOverflow自体には、ユーザー、質問、回答、コメントなどの個別の名前空間がありますが、これらもかなり明白です。
uuid ns_user = uuidv5(ns_base, 'user');
uuid ns_question = uuidv5(ns_base, 'question');
uuid ns_answer = uuidv5(ns_base, 'answer');
uuid ns_comment = uuidv5(ns_base, 'comment');
この特定の質問は#10867405なので、そのUUIDは次のようになります。
uuid here = uuidv5(ns_question, '10867405');
このプロセスにはnothingランダムがあるため、同じロジックに従うと誰でも同じ答えが得られますが、UUID名前空間は非常に広大であるため(事実上、122ビットのセキュリティ暗号化ハッシュ)は、他の名前空間/名前のペアから生成されたUUIDと決して衝突しません。