2012-03-08 31 views
5

Người ta nghĩ rằng sự phân bố byte trong các hướng dẫn là ngẫu nhiên, hoặc ít nhất là rất bằng phẳng. Lý do mà Guid.NewGuid luôn tạo ra guids có chứa 4? có biểu diễn chuỗi chứa 4?Tại sao Guid.NewGuid không bao giờ sản xuất Hướng dẫn không chứa 4?

Đó là

Guid.NewGuid(). ToString ("N"). Chứa ("4")

luôn luôn là sự thật.

Kiểm tra nhanh chỉ ra rằng hầu hết các byte xảy ra trong khoảng 85% các hướng dẫn, nhưng 4 xảy ra trong 100%. Có lẽ điều này không quan trọng, nhưng tôi rất muốn biết tại sao.

[Chỉnh sửa]
Tôi không quá rõ ràng, do đó được chỉnh sửa để cải thiện sự rõ ràng về câu hỏi của tôi.


Chạy ứng dụng này. Không chính xác sâu sắc, nhưng vui vẻ.

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 
} 

}

Tôi cần tìm hiểu cách định dạng nội dung chính xác tại đây một ngày nào đó. Stackoverflow là grrr-ăn.

+5

[GUID không ngẫu nhiên] (http://en.wikipedia.org/wiki/GUID#Algorithm). –

+0

@KonradRudolph Đó là lý do tại sao tôi rất cụ thể về _distribution_ của byte là ngẫu nhiên ** hoặc ** ít nhất là rất bằng phẳng. Tôi biết họ không hoàn toàn ngẫu nhiên, mặc dù không phải lý do. –

+2

Ngừng đốt cháy các gu của chúng tôi! – U1199880

Trả lời

8

GUID không hoàn toàn ngẫu nhiên, vị trí nơi 4 cho biết "loại" GUID được tạo.

Xem http://en.wikipedia.org/wiki/Globally_unique_identifier

+1

Tuyệt vời. Tôi chỉ vấp phải điều này khi tôi thực hiện kiểm soát treeview với sự hỗ trợ cho tìm kiếm như bạn-loại. Để kiểm tra, tôi đã tạo ra những cây khổng lồ và bán ngẫu nhiên, sử dụng ToString ("N") trên Guid để nhận các văn bản mà tôi có thể tìm kiếm. Bộ điều khiển hiển thị số lượng kết quả trùng khớp, làm nổi bật các nút khớp, cuộn kết quả đầu tiên vào xem và cho phép người dùng điều hướng tiếp theo/kết hợp trước (w/wrap-around). Nó hoạt động tốt, nhưng tôi đã rất ngạc nhiên khi thấy 100.000 trận đấu trong cây 100.000 cây của tôi khi tôi gõ "4". :) –

Các vấn đề liên quan