2011-08-23 13 views
11

This articleはGuidsの生成方法を説明しています。Guidをデコードして、いつ、どこで生成されたのか調べることはできますか?

私の質問は、私のウェブファーム内のどのマシンがこのGuidをいつ作成したかを知る方法はありますか?

+0

はい - これを行うために必要なすべての情報は、その記事とリンクされたインターネットドラフトです。これは、あなたがそのアルゴリズムの仕様/詳細を見つける必要がある別のアルゴリズムで生成された場合、そのアルゴリズムでGUIDが生成されたことを前提としています。バリアント項目(リンクされたメモに記載)を使用して、使用されたレイアウトバリアントを決定することができます。 – Justin

答えて

13

ニールフェンウィックは正しいです。しかし、我々はその構造を我々の利益に利用することができる。

版4(.NET)

バージョン4つのUUIDは、乱数にのみ依存する方式を使用します。このアルゴリズムは、バージョン番号と2つの予約ビットを設定します。他のすべてのビットは、ランダムまたは疑似ランダムデータソースを使用して設定されます。バージョン4のUUIDは、xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxxの形式を持ち、xは任意の16進数字であり、yは8,9、A、またはBのいずれかです。 f47ac10b-58cc-4372-a567-0e02b2c3d479。

バージョンフィールドを使用

私たちは、バイト8の最初のニブルを変更するのは自由です。 17台未満のマシンがある場合は、それぞれのマシンで作成されたGUIDを変更してマシンを識別できます。

static Guid NewSystemGuid(int machine) 
{ 
    if (machine < 0 | machine > 0xF) 
     throw new ArgumentOutOfRangeException("machine"); 
    var g = Guid.NewGuid(); 
    var arr = g.ToByteArray(); 
    arr[7] = (byte)((machine << 4) | (arr[7] & 0xF)); 
    return new Guid(arr); 
} 

static int ExtractMachine(Guid guid) 
{ 
    var arr = guid.ToByteArray(); 
    return (arr[7] >> 4) & 0xF; 
} 

バージョンフィールドを使用して、あなたの走行距離は変更になる場合がありますので、「y」を

Yを変更する場合、私はわからないが、GUIDの一意性を変更します。最初の解決策に固執する機械が17台未満の場合。

static Guid NewSystemGuid(int machine) 
{ 
    if (machine < 0 | machine > 0xFF) 
     throw new ArgumentOutOfRangeException("machine"); 

    var m1 = machine & 0xF; 
    var m2 = (machine >> 4) & 0xF; 

    var g = Guid.NewGuid(); 
    var arr = g.ToByteArray(); 
    arr[7] = (byte)((m1 << 4) | (arr[7] & 0xF)); 
    arr[8] = (byte)((m2 << 4) | (arr[8] & 0xF)); 
    return new Guid(arr); 
} 

static int ExtractMachine(Guid guid) 
{ 
    var arr = guid.ToByteArray(); 
    return 
     ((arr[7] >> 4) & 0xF) | 
     (((arr[8] >> 4) & 0xF) << 4); 
} 

あなたはまだ表現するために、最後の2ビットを使用して(63のマシンの量を制限することによって、「Y」の値を保持することができるバージョンと「Y」(Reduxの)

を使用'Y' の4つの可能な値):

static Guid NewSystemGuid(int machine) 
{ 
    if (machine < 0 | machine > 0x3F) 
     throw new ArgumentOutOfRangeException("machine"); 

    var m1 = machine & 0xF; 
    var m2 = (machine >> 4) & 0xF; 

    var g = Guid.NewGuid(); 
    var arr = g.ToByteArray(); 
    arr[7] = (byte)((m1 << 4) | (arr[7] & 0xF)); 

    var y = (arr[8] >> 4) & 0xF; 
    switch (y) 
    { 
     case 0x8: 
      arr[8] = (byte)((m2 << 4) | (arr[8] & 0xF)); 
      break; 
     case 0x9: 
      arr[8] = (byte)(((m2 | 0x8) << 4) | (arr[8] & 0xF)); 
      break; 
     case 0xA: 
      arr[8] = (byte)(((m2 | 0x4) << 4) | (arr[8] & 0xF)); 
      break; 
     case 0xB: 
      arr[8] = (byte)(((m2 | 0xC) << 4) | (arr[8] & 0xF)); 
      break; 
     default: 
      throw new Exception(); 
    } 
    return new Guid(arr); 
} 

static int ExtractMachine(Guid guid) 
{ 
    var arr = guid.ToByteArray(); 
    return 
     ((arr[7] >> 4) & 0xF) | 
     (((arr[8] >> 4) & 0x3) << 4); 
} 

使用バージョン1つのGUID

あなたは可能性がアルバージョン1のGUIDを使用することができます。

class SequentialGuid 
{ 
    [DllImport("rpcrt4.dll", SetLastError = true)] 
    static extern int UuidCreateSequential(out Guid guid); 

    public static Guid NewGuid() 
    { 
     Guid guid; 
     UuidCreateSequential(out guid); 
     return guid; 
    } 

    public static byte[] ExtractMacAddress(Guid guid) 
    { 
     var arr = guid.ToByteArray(); 
     // Require version 1. 
     if (((arr[7] >> 4) & 0xF) != 1) 
      throw new ArgumentOutOfRangeException("guid", "GUID is required to be a sequential (version 1) GUID."); 

     var macLong = BitConverter.ToInt64(arr, arr.Length - 8); 
     macLong = IPAddress.NetworkToHostOrder(macLong); 
     arr = BitConverter.GetBytes(macLong); 
     Array.Resize(ref arr, 6); 

     return arr; 
    } 
} 
+0

これは大きな努力をしています:) – Faisal

+0

@Faisalコメントがあなたの問題を解決するならそれを受け入れることを忘れないでください:)。 –

+0

私はそれを覚えました。私は他のいくつかの答えを待っていました。受け入れられた:) – Faisal

関連する問題