c# – 估计GUID内的数字发生概率

前端之家收集整理的这篇文章主要介绍了c# – 估计GUID内的数字发生概率前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
最近我决定调查用 Guid.NewGuid method生成的全球唯一标识符的随机程度(这也是这个问题的范围).我记录了自己在 pseudorandom numbers,pseudorandomness,我很眩目,发现甚至有 random numbers generated by radioactive decay.无论如何,我会让你发现自己更多的细节关于这样有趣的讲座.

为了继续我的问题,GUID的另一件重要的事情是:

V1 GUIDs which contain a MAC address and time can be identified by the
digit “1” in the first position of the third group of digits,for
example {2F1E4FC0-81FD-11DA-9156-00036A0F876A}.

V4 GUIDs use the later algorithm,which is a pseudo-random number.
These have a “4” in the same position,for example
{38A52BE4-9352-453E-AF97-5C3B448652F0}.

将它放在句子中,Guid将始终将数字4(或1,但不在我们的范围内)作为其组成部分之一.

对于我的GUID随机测试,我决定计算一些越来越大的GUID集合中的位数,并将其与数字发生的统计概率进行比较,期望发生.或者至少我希望我做到了(请原谅任何统计公式的错误,我只是尝试我最好的猜测来计算价值).我使用了下面列出的一个小型C#控制台应用程序.

  1. class Program
  2. {
  3. static char[] digitsChar = "0123456789".tocharArray();
  4. static decimal expectedOccurrence = (10M * 100 / 16) * 31 / 32 + (100M / 32);
  5. static void Main(string[] args)
  6. {
  7. for (int i = 1; i <= 10; i++)
  8. {
  9. CalculateOccurrence(i);
  10. }
  11. }
  12.  
  13. private static void CalculateOccurrence(int counter)
  14. {
  15. decimal sum = 0;
  16. var sBuilder = new StringBuilder();
  17. int localCounter = counter * 20000;
  18. for (int i = 0; i < localCounter; i++)
  19. {
  20. sBuilder.Append(Guid.NewGuid());
  21. }
  22.  
  23. sum = (sBuilder.ToString()).tocharArray()
  24. .Count(j => digitsChar.Contains(j));
  25.  
  26. decimal actualLocalOccurrence = sum * 100 / (localCounter * 32);
  27.  
  28. Console.WriteLine(String.Format("{0}\t{1}",expectedOccurrence,Math.Round(actualLocalOccurrence,3)
  29. ));
  30. }
  31. }

以上程序的输出为:

  1. 63.671875 63.273
  2. 63.671875 63.300
  3. 63.671875 63.331
  4. 63.671875 63.242
  5. 63.671875 63.292
  6. 63.671875 63.269
  7. 63.671875 63.292
  8. 63.671875 63.266
  9. 63.671875 63.254
  10. 63.671875 63.279

所以即使理论上的发生预计为63.671875%,实际值约在63.2%左右.

这个差异如何解释?我的公式有错吗? Guid算法中有其他“晦涩”的规则吗?

解决方法

在版本4 GUID中,第三组中的第一个字符是4.第四组中的第一个字符是8,9,a或b之一.该规范没有说明如何生成第四组中的第一个字符.这可能会甩掉你的结果.

如果您想进一步调查,您需要跟踪每个十六进制数字在每个位置出现的频率.我怀疑会揭示差异,并帮助您确定您的理论估计是否关闭,或伪随机算法有轻微的偏见.

猜你在找的C#相关文章