如何种子GUID生成?

CJ7*_*CJ7 8 .net c# random guid

在.NET中编写函数以生成基于种子的GUID的最简单方法是什么,这样我才能对其唯一性有更大的信心?

string GenerateSeededGuid(int seed) { /* code here */ }
Run Code Online (Sandbox Code Playgroud)

理想情况下,种子将来自CryptGenRandom,它描述了它的随机数生成如下:

此函数生成的数据是加密随机的.它比典型的随机数生成器(如C编译器附带的生成器)生成的数据更随机.

此函数通常用于生成随机初始化向量salt值.

软件随机数生成器的工作方式基本相同.它们以随机数开始,称为种子,然后使用算法基于它生成伪随机比特序列.这个过程中最困难的部分是获得一个真正随机的种子.这通常基于用户输入延迟或来自一个或多个硬件组件的抖动.

使用Microsoft CSP,CryptGenRandom使用其他安全组件使用的相同随机数生成器.这允许许多过程对系统范围的种子做出贡献.CryptoAPI为每个用户存储一个中间随机种子.为了形成随机数生成器的种子,调用应用程序提供它可能具有的位 - 例如,鼠标或键盘定时输入 - 然后将其与存储的种子和各种系统数据以及用户数据(例如进程ID和线程ID,系统时钟,系统时间,系统计数器,内存状态,可用磁盘集群,散列用户环境块.该结果用于对伪随机数发生器(PRNG)进行种子处理.[...]如果一个应用程序可以访问一个好的随机源,它可以填充在调用CryptGenRandom之前,pbBuffer缓冲区包含一些随机数据 .然后,CSP使用此数据进一步随机化其内部种子.在调用CryptGenRandom之前省略初始化pbBuffer缓冲区的步骤是可以接受的 .

小智 15

tldr; 使用Guid.NewGuid而不是试图发明另一种"更随机"的方法.(我可以想到从种子创建UUIDvX的唯一原因是需要一个可预测的,可重置的序列.但是,GUID可能也不是最好的方法2.)

通过定义为有限范围 - 128 位减去 6个版本位,因此对于v4来说122位唯一性 - 只有这么多(尽管数量极大! 天文数字太大!)"唯一"标识符.

由于鸽笼原则,只有很多鸽笼.如果鸽子最终继续繁殖,每只鸽子的洞数就不够了.由于生日悖论,假设完全随机,两只鸽子将在它们全部填满之前尝试为同一鸽笼而战.因为没有Master Pigeonhole List 1,所以无法阻止.此外,并非所有动物都是鸽子3.

虽然不保证 GUID发电机将被使用,.NET使用底层操作系统调用,这是一个GUIDv4(又名随机UUID)生成自Windows 2K.据我所知 - 或者非常关心 - 这对于这样的目的而言是随机的.它已经过十多年的审查,并没有被取代.


来自维基百科:

..只有在未来100年内每秒产生10亿UUID之后,创建一个副本的概率大约为50%.如果地球上每个人拥有6亿UUID,则一次重复的概率约为50%.

1虽然仍有一组有限的Pigeonholes,UUIDv1(又称MAC UUID) - 假设独特的时空 - 保证生成确定性的唯一数字(在给定的机器上每秒生成一些"相对较小"的理论最大UUID数量) ).不同的鸽子生活在不同的平行维度 - 真棒!

2 Twitter在其自己的分布式Unique-ID方案中使用平行维度的Snowflakes.

3只兔子喜欢住在Burrows,而不是Pigeonholes.GUID 的使用也充当隐式并行分区.只有当重复的GUID 用于相同的目的时才会出现与冲突相关的问题.想想有多少重复的自动增量数据库主键!


San*_*nen 13

您在GenerateSeededGuid方法中真正需要做的就是创建一个128位的随机数并将其转换为Guid.就像是:

public Guid GenerateSeededGuid(int seed)
{
  var r = new Random(seed);
  var guid = new byte[16];
  r.NextBytes(guid);

  return new Guid(guid);
}
Run Code Online (Sandbox Code Playgroud)

  • +1对于"来自种子",尽管1)这可能最终导致无效的UUID(错误的版本位)和2)**生成更多的冲突**因为种子在范围内受限制; GUID被设计为"具有非常低的碰撞机会",因此没有理由相信自定义的一次性随机生成方法可以更好地工作或者更随机,GUIDv4找到Windows 2k + (10认同)
  • 批准整个文档的单元测试 - 从这种技术中获益.谢谢! (3认同)
  • @pst:我同意.我个人认为没有理由不使用`NewGuid`. (2认同)