2012-03-08 3 views
5

guids의 바이트 분포가 무작위이거나 최소한 평평하다고 생각할 것입니다. Guid.NewGuid가 항상 guid 에 4를 포함하는 이유는 무엇입니까? 문자열 표현에 4? Guid.NewGuid(). ToString ("N")Guid.NewGuid가 4를 포함하지 않는 Guid를 생성하지 않는 이유는 무엇입니까?

입니다

은. 포함 ("4")

은 항상 사실이다.

빠른 테스트는 대부분의 바이트가 Guid의 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 먹는입니다.

+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

좋아요. 나는 treeview 컨트롤을 search-as-you-type에 대한 지원과 함께 만들었을 때 이것을 발견했습니다. 테스트를 위해 Guid에서 ToString ("N")을 사용하여 검색 할 수있는 텍스트를 얻기 위해 거대하고 준 임의의 트리를 만들었습니다. 컨트롤에는 일치하는 노드의 수를 표시하고, 일치하는 노드를 강조 표시하고, 첫 번째 일치 항목을보기로 스크롤하고, 사용자가 다음/이전 일치를 탐색하도록합니다 (줄 바꿈 포함). 잘 작동했지만 "4"를 입력했을 때 10 만 개의 노드 트리에서 100,000 개의 일치 항목을 보게되어 매우 놀랐습니다. :) –

관련 문제