2012-03-08 19 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

相关问题