随机是如何System.Guid.NewGuid()? (拿两个)

在开始将其标记为重复之前,请将我读出来。 另一个问题有一个(很可能)不正确的接受答案。

我不知道.NET如何生成它的GUID,可能只有微软,但它很可能只是调用CoCreateGuid()。 但是该函数被记录为调用UuidCreate()。 而且创建UUID的算法也有很好的文档记录。

长话短说,尽可能地,似乎System.Guid.NewGuid()确实使用版本4的UUID生成算法,因为它生成的所有GUID都与条件相匹配(请参阅我自己,我尝试了几百万个GUID,它们全部匹配)。

换句话说,除了一些已知位以外,这些GUID 几乎是随机的。

这又提出了一个问题 - 随机性多么随意? 正如每个优秀的小程序员都知道的那样,伪随机数算法只与其种子(又名熵)一样随机。 那么UuidCreate()的种子是什么? PRNG重新种植了多少? 它是密码强大的,还是我可以期待如果两台计算机不小心同时调用System.Guid.NewGuid()时,同样的GUID开始System.Guid.NewGuid() ? 如果收集足够多的顺序生成的GUID,PRNG的状态是否会被猜测?

补充:为了澄清,我想知道我可以如何信任它,因此 - 我可以在哪里使用它。 所以,我们在这里建立一个粗略的“随机性”尺度:

  • 基本随机性,以当前时间为种子。 可用于在纸牌中洗牌,但很少碰撞,即使没有尝试也很容易出现。
  • 更高级的随机性,不仅使用时间,而且还使用其他机器特定的种子因素。 也许在系统启动时也只播种一次。 这可以用于在数据库中生成ID,因为重复是不太可能的。 尽管如此,这对安全性并不好,因为可以用足够的努力预测结果。
  • 使用设备噪声或其他先进的种子随机性来隐写随机。 每次调用都重播种子,或者至少经常重播。 可以用于发送给不受信任方的会话ID等。
  • 我在思考是否可以将它们用作数据库ID的同时,也想到了这个问题,以及Guid.comb算法与System.Guid.NewGuid()一起实现(像NHibernate一样)是否会有缺陷。


    对相关问题的接受答案是:

    GUID不保证随机性,它保证了唯一性。 如果你想随机,使用随机生成一个字符串。

    其他任何东西都是实现细节(可能会更改)。

    更新:为了让我的观点更清晰:即使当前的.NET 3.5实现产生了一个真正的随机guid(情况并非如此),但不能保证将来会出现这种情况,或者BCL的其他实现也是如此(如Mono,Silverlight,CF等)

    更新2:UUID的格式由RFC4122指定。 第6节对安全做出明确声明:

    不要以为UUID很难猜测; 例如,它们不应该被用作安全功能(仅仅拥有授权访问权的标识符)。 可预测的随机数字来源会加剧这种情况。


    有些人已经暗示了这一点,但我想重复一遍,因为那里似乎有一种误解:

    随机性和唯一性是正交的概念。

    随机数据可以是唯一的或冗余的,同样独特的数据可以使用随机源或确定性源(想象一个全局计数器,锁定并增加每个创建的GUID)。

    GUID被设计为独特的,而不是随机的。 如果.NET生成器似乎使用随机输入,那很好。 但不要将它作为随机性的来源,不要将其作为密码学或其他任何用途(特别是,你期望得到什么分布函数?)。 另一方面,您可以合理确定由.NET创建的GUID即使在大量情况下也是唯一的。


    随机的定义决不涉及全局唯一的定义。

    翻转硬币两次,得到HH,HT,TH,TT都是随机的。 HH与HT一样随机。

    翻转一个“特殊”硬币两次,并保证你只会得到HT或TH是唯一的。

    链接地址: http://www.djcxy.com/p/17713.html

    上一篇: How Random is System.Guid.NewGuid()? (Take two)

    下一篇: Determining why github says "Closed with unmerged commits"