2012-03-08 51 views
5

有人會認爲在GUID的字節數的分佈是隨機的,或者至少是非常平坦。那是什麼Guid.NewGuid總是讓GUID的 包含一個4的原因嗎? 其字符串表示包含4?爲什麼Guid.NewGuid從來沒有產生GUID,它不包含4?

Guid.NewGuid()。的ToString( 「N」)。包含( 「4」)

是總是如此。

快速測試表明,發生在的GUID約85%,最字節,但發生在100%4。也許這沒關係,但我很想知道爲什麼。

[編輯]
我不是非常清楚,所以編輯,以提高我的問題的清晰度。


運行此操作。不完全是深刻的,但有趣。

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吃。

+5

[GUID是不是隨機](http://en.wikipedia.org/wiki/GUID#Algorithm)。 – 2012-03-08 14:25:50

+0

@KonradRudolph這就是爲什麼我是如此具體的關於是隨機**或**至少是非常平坦的字節_distribution_。我知道他們不是很隨意,但不是爲什麼。 – 2012-03-08 15:11:33

+2

停止燃燒我們的指導! – U1199880 2013-01-08 17:38:04

回答

8

GUID是不完全隨機的,其中4是現貨指示被生成的GUID「類型」。

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

+1

太好了。我只是偶然發現了這一點,當我做了一個支持「即搜索」類型的樹形控件。爲了測試,我使用Guid上的ToString(「N」)來製作巨大且準隨機的樹,以獲取我可以搜索的文本。控件顯示有多少匹配,突出顯示匹配的節點,將第一個匹配滾動到視圖中,並讓用戶導航next/prev匹配(w/wrap-around)。它運行良好,但當我輸入「4」時,在我的100,000個節點樹中看到100,000個匹配,我感到非常驚訝。 :) – 2012-03-08 15:09:36

相關問題