Почему Guid.NewGuid никогда не создает Guid, который не содержит 4? - PullRequest
5 голосов
/ 08 марта 2012

Можно подумать, что распределение байтов в направляющих было случайным или, по крайней мере, очень плоским. По какой причине Guid.NewGuid всегда делает guids , который содержит 4? , чье строковое представление содержит 4?

То есть

Guid.NewGuid (). ToString ( "N"). Содержит ( "4")

всегда верно.

Быстрое тестирование показывает, что большинство байтов встречается примерно в 85% единиц, а 4 - в 100%. Может быть, это не имеет значения, но я хотел бы знать, почему.

[Изменить]
Я был не совсем ясен, поэтому отредактировал, чтобы улучшить ясность моего вопроса.


Запустите это. Не совсем глубоко, но весело.

using System; using System.Diagnostics;</p> <p>namespace ConsoleApplication1 { class Program { static bool paused, exit;</p> <pre><code> 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 }

}

Мне нужно научиться правильно форматировать вещи здесь когда-нибудь. Переполнение стека grrr-eat.

1 Ответ

8 голосов
/ 08 марта 2012

GUID не являются полностью случайными, точка, где 4 указывает «тип» генерируемого GUID.

См. http://en.wikipedia.org/wiki/Globally_unique_identifier

...