最初の部分 (または任意の部分) がユーザーが選択したプレフィックスである有効な GUID/UUID を生成する方法があるかどうか疑問に思います。
つまり、GUID の形式は AAAAAAAA-BBBB-CCCC-DDDD-DDDDDDDDDDDD で、任意の部分を事前定義された値 (理想的には AAA) に設定したいと考えています。目標は、GUID をグローバルに一意にすることですが、暗号的に安全である必要はありません。
申し訳ありませんが、GUIDからの情報が多すぎます。あなたの質問とあなた自身の答え/更新の両方から要約すると、あなたはそれをしたいです
これは不可能です。証明:可能であれば、GUID G1を生成し、別のGUIDG2を生成することができます。どちらも標準を無視し、同じ予約済みプレフィックスを使用し、他のビットの個人的なスキームは制御できないため、GUIDG1がGUIDG2と衝突する可能性があります。GUIDの非衝突プロパティは、GUID標準に準拠することから得られます。
衝突を防ぐメカニズムは、確かに本質的にプライバシーに敏感です。GUID G1をランダムに生成する場合、次の2つの条件が満たされると、ランダムGUIDが一意であることを保証できます。
管理下にあるサブセット外のGUIDの場合、(2)を保証することはできません。しかし、重複しないGUIDのサブセットを1人の人にどのように割り当てますか?NICのMACを使用することは、簡単で効果的な方法です。他の手段も可能です。しかし、いずれにせよ、そのようなサブセットの単なる存在はプライバシーを暗示しています。それは誰かのものでなければならず、それが私なのか他の誰かなのかを判断できなければなりません。2つのランダムなGUIDG1とG2が同じサブセット(つまり、person)に属しているかどうかを証明するのは少し難しいですが、現在のスキーム(反対)はそれを隠そうとしません。
うーん...では、基本的に12バイトのGUIDが必要ですか?最初の4バイト(AAA)の一意性を削除すると、既存のアルゴリズムが壊れてしまうため、独自のアルゴリズムを考え出す必要があります。
関連するRFCによると、GUID形式は次のように分類されます。
UUID = time-low "-" time-mid "-"
time-high-and-version "-"
clock-seq-and-reserved
clock-seq-low "-" node
time-low = 4hexOctet
time-mid = 2hexOctet
time-high-and-version = 2hexOctet
clock-seq-and-reserved = hexOctet
clock-seq-low = hexOctet
node = 6hexOctet
hexOctet = hexDigit hexDigit
hexDigit =
"0" / "1" / "2" / "3" / "4" / "5" / "6" / "7" / "8" / "9" /
"a" / "b" / "c" / "d" / "e" / "f" /
"A" / "B" / "C" / "D" / "E" / "F"
そこにある唯一の静的データは、バージョン(4ビット)と予約済み/バリアント(2〜3ビット)です。「ユーザー指定」バージョンが許可されているかどうかはわかりませんが、バージョンIDとして1111を使用すれば、当面は安全だと思います。既存のバージョンはセクション4.1.3にありますが、これまでに定義されているのは5つだけです...これにより、衝突前にさらに11のリビジョンが提供されます。
したがって、6ビットまたは7ビットの明瞭さで生きることができる場合は、Guid.NewGuid()。ToByteArray()と、ビットをいじった後に新しいGuidを作成することの組み合わせでそこに到達するはずです。
最初の部分 (または任意の部分) がユーザーが選択したプレフィックスである GUID/UUID を作成することはできませんが、独自の関数を記述して、同じ数 (36/38) の文字で一意の ID を作成することはできます...
最近、同様のニーズがありました。次のGUIDが必要でした。
ご想像のとおり、私はすべきでないことをしていました。
コメントの1つで、必要なプレフィックスが付いたGUIDにヒットするまで、GUIDジェネレーターを実行させることができると述べています。それが私が取った戦術です。コードは次のとおりです。
using System;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string target_prefix = "dead";
while (true)
{
Guid g = Guid.NewGuid();
string gs = g.ToString();
if (gs.Substring(0, target_prefix.Length) == target_prefix)
{
Console.WriteLine("Match: " + gs);
}
else
{
//Console.WriteLine("Mismatch: " + gs);
}
}
}
}
}
プレフィックスが小さい場合は、一致がより迅速に生成されます。ターゲットプレフィックスのすべての桁の16倍の長さだと思います。
簡単に Guid を作成し、プレフィックスを好きなように変更できます。これは OS プロジェクトで見たことがあります。同じ質問が投げられ、希望するプレフィックスに一致するまで非常に多くの GUID を生成することで解決されました (うーん!)。
Guid g = Guid.NewGuid();
string gs = g.ToString();
Guid f = new Guid(string.Format("{0}-{1}", "AAAAAAAA", gs.Substring(gs.IndexOf('-') + 1)));
良くありませんが、機能します。
この主題の他の投稿で私を悩ませたのは、GUID はグローバルに一意でなければならないということです。これはすべての場合に間違っています。一意の GUID を生成するのに十分な余地がありますが、グローバルに一意に保証されるものは何もありません。GUID の生成には時間も考慮されません。
ありがとう。これらの試みに関する私の問題は、 Raymond Chenが指摘したように、それらが世界的に一意であることが保証されていないことです。一意の GUID を生成する別のアルゴリズムがあるかどうか疑問に思っていました。以前はタイムスタンプや NIC MAC アドレスを使用する実装があったことを覚えていますが、それらは暗号強度が低く、プライバシー上の懸念があるため、現在は使用されていません。
私は疑問に思います: 私が自分自身を作るだけなら、私は大丈夫なはずですか? ウィキペディアによると:
データ 4 の 2 番目のバイトの最上位ビットの 1 ~ 3 は、GUID の型バリアントを定義します。
パターン 説明
0 ネットワーク コンピューティング システムの下位互換性
10 標準
110 Microsoft コンポーネント オブジェクト モデルの下位互換性。これには、IUnknown や IDispatch などの重要なインターフェイスの GUID が含まれます。
111 将来の使用のために予約されています。Data3 の上位 4 ビットは、バージョン番号と使用されるアルゴリズムを定義します。
したがって、Data3/Data4 で何かを構成する場合、通常は他の GUID と競合しない独自の実装を作成しますが、もちろんそれに関連するリスクが常に少しあるため、その前に確認したいと思いました。真の一意の ID を生成する古い/使用されなくなったアルゴリズムがある場合。