有人会认为guid中的字节分布是随机的,或者至少是非常平坦的。 Guid.NewGuid总是使guids 包含一个4?的字符串表示包含4的原因是什么?
那是
Guid.NewGuid()。的ToString( “N”)。包含( “4”)
总是如此。
快速测试表明大多数字节出现在大约85%的Guid中,但是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
}
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-eat。
答案 0 :(得分:8)
GUID不是完全随机的,4的位置表示正在生成的GUID的“类型”。