2012-03-08 7 views
5

guidのバイトの分布はランダムであると思うでしょう。 Guid.NewGuidが常にguid に4を含む理由は何ですか? 文字列表現に4?なぜGuid.NewGuidは4を含まないGuidを生成しませんか?

Guid.NewGuid(ある

)。ToStringメソッド( "N")。( "4")が含まれ

は常に真です。

クイックテストでは、ほとんどのバイトがGuidsの約85%で発生しますが、4つは100%で発生します。たぶんこれは問題ではないが、私は理由を知りたい。

[編集]
私は非常に明確ではなかったので、私の質問の明確さを改善するために編集しました。


これを実行します。正確ではないが、楽しい。

using System; using System.Diagnostics;

namespace ConsoleApplication1 { class Program { static bool paused, exit;

static void Main(string[] args) 
    { 
     Console.WindowHeight = (int)(0.8*Console.LargestWindowHeight); 

     var reportInterval = TimeSpan.FromSeconds(0.15); 
     WriteLine(ConsoleColor.White, "X key to exit."); 

     Guid guid; 
     byte[] bytes; 
     long guidCount = 0; 
     var counts = new long[256]; 
     var watch = Stopwatch.StartNew(); 
     var cursorPos = new CursorLocation(); 

     while (!exit) 
     { 
      if (!paused) 
      { 
       guid = Guid.NewGuid(); 
       bytes = guid.ToByteArray(); 
       ++guidCount; 

       for (int i = 0; i < 16; i++) 
       { 
        var b = bytes[i]; 
        ++counts[b]; 
       } 

       if (watch.Elapsed > reportInterval) 
       { 
        cursorPos.MoveCursor(); 
        DumpFrequencies(counts, guidCount); 
        watch.Restart(); 
       } 
      } 

      if (Console.KeyAvailable) 
      { 
       ProcessKey(Console.ReadKey()); 
      } 
     } 
    } 


    static void ProcessKey(ConsoleKeyInfo keyInfo) 
    { 
     switch (keyInfo.Key) 
     { 
      case ConsoleKey.P: 
       paused = !paused; 
       break; 
      case ConsoleKey.X: 
       exit = true; 
       break; 
     } 
    } 


    static void DumpFrequencies(long[] byteCounts, long guidCount) 
    { 
     Write("\r\n{0} GUIDs generated. Frequencies:\r\n\r\n", guidCount); 

     const int itemWidth = 9; 
     int colCount = Console.WindowWidth/(itemWidth*2); 

     for (int i = 0; i < 256; i++) 
     { 
      var f = (double)byteCounts[i]/(16 * guidCount); 
      Write(RightAdjust(itemWidth, "{0:x}", i)); 
      Write(GetFrequencyColor(f), " {0:p}".PadRight(itemWidth), f); 
      if ((i + 1) % colCount == 0) Write("\r\n"); 
     } 
    } 


    static ConsoleColor GetFrequencyColor(double f) 
    { 
     if (f < 0.003) return ConsoleColor.DarkRed; 
     if (f < 0.004) return ConsoleColor.Green; 
     if (f < 0.005) return ConsoleColor.Yellow; 
     return ConsoleColor.White; 
    } 


    static string RightAdjust(int w, string s, params object[] args) 
    { 
     if (args.Length > 0) 
      s = string.Format(s, args); 
     return s.PadLeft(w); 
    } 

    #region From my library, so I need not include that here... 
    class CursorLocation 
    { 
     public int X, Y; 
     public CursorLocation() 
     { 
      X = Console.CursorLeft; 
      Y = Console.CursorTop; 
     } 

     public void MoveCursor() 
     { 
      Console.CursorLeft = X; 
      Console.CursorTop = Y; 
     } 
    } 


    static public void Write(string s, params object[] args) 
    { 
     if (args.Length > 0) s = string.Format(s, args); 
     Console.Write(s); 
    } 


    static public void Write(ConsoleColor c, string s, params object[] args) 
    { 
     var old = Console.ForegroundColor; 
     Console.ForegroundColor = c; 
     Write(s, args); 
     Console.ForegroundColor = old; 
    } 


    static public void WriteNewline(int count = 1) 
    { 
     while (count-- > 0) Console.WriteLine(); 
    } 


    static public void WriteLine(string s, params object[] args) 
    { 
     Write(s, args); 
     Console.Write(Environment.NewLine); 
    } 


    static public void WriteLine(ConsoleColor c, string s, params object[] args) 
    { 
     Write(c, s, args); 
     Console.Write(Environment.NewLine); 
    } 
    #endregion 
} 

}

私はいつの日か、正しくここにものをフォーマットする方法を学ぶ必要があります。 Stackoverflowはgrrr-eatです。

+5

[GUIDがランダムではない](http://en.wikipedia.org/wiki/GUID#Algorithm)。 –

+0

@ KonradRudolphだからこそ、私は、ランダムな**または**少なくともフラットなバイトの_分布について非常に具体的でした。私は彼らがなぜ無作為ではなかったのか分かっていた。 –

+2

私たちのguidsを燃やすことを停止! – U1199880

答えて

8

GUIDは完全にランダムではありません.4がある場所は、生成されているGUIDの「タイプ」を示します。

見るhttp://en.wikipedia.org/wiki/Globally_unique_identifier

+1

素晴らしい。私はこれを見つけたばかりのとき、私はタイプとしての検索をサポートするツリービューコントロールを作った。テストするために、GuidでToString( "N")を使って検索できるテキストを得るために、巨大で疑似ランダムなツリーを作成しました。コントロールには一致するノードの数が表示され、一致するノードが強調表示され、最初の一致が表示にスクロールされ、ユーザーは次の/前一致(wrap-around)をナビゲートできます。それはうまくいきましたが、 "4"と入力したときに100,000ノードのツリーに100,000件の一致が見られることに非常に驚きました。 :) –

関連する問題