为什么我们需要 GUID 的规范格式?

Why do we need a canonical format for the GUID?

一个辛苦的工作日,我注意到 GUIDs 我一直在使用通常的 .NET Guid.NewGuid() 方法生成,在第三个块的开头有相同的数字 4

efeafa5f-fe21-4ab4-ba82-b9eefd5fa225
480b64d0-6762-4afe-8496-ac7cf3292898
397579c2-a4f4-4611-9fda-16e9c1e52d6a
...

每秒钟大约有十个出现在屏幕上。在第五个 GUID 之后,我一直在关注这个模式。最后,最后一个内部有相同的四个位,我认为我是一个幸运的人。我回到家,觉得整个世界都为我这样一个杰出的人敞开了大门。下周我找到了一份新工作,打扫了我的房间并打电话给我的 parents.

但今天我又遇到了同样的情况。千遍。我再也感觉不到天选者了。

我用谷歌搜索了一下,现在我知道 UUID 和一种规范格式,其中 4 个保留位用于 version,2 个保留位用于 variant

这里有一段可以用来试验的片段:

static void Main(string[] args)
{
    while (true)
    {
        var g = Guid.NewGuid();
        Console.WriteLine(BitConverter.ToString(g.ToByteArray()));
        Console.WriteLine(g.ToString());
        Console.ReadLine();
    }
}

但还有一件事我不明白(除了如何继续生活)。为什么我们需要这些保留位?我看到它有何危害 - 暴露内部实施细节,更多的冲突(仍然没有什么可担心的,但总有一天......),更多的自杀 - 但我没有看到任何好处。你能帮我找到吗?

这样一来,如果您更新算法,就可以更改该数字。否则 2 种不同的算法可能会出于不同的原因产生完全相同的 UUID,从而导致冲突。它是一个版本标识符。

例如,考虑一个设计简单的 UUID 格式:

00000000-00000000
  time  -   ip

现在假设我们出于某种原因将该格式更改为:

00000000-00000000
   ip   -  time

当 IP 为 12.34.56.78 的 machine 在时间 01234567 使用第一种方法生成 UUID 时,这可能会产生冲突,随后 IP 为 01.23.45.67 的第二个 machine 生成使用较新方法的时间为 12345678 的 UUID。但是如果我们为版本标识符保留一些位,这不可能导致冲突。

值 4 具体指的是随机生成的 UUID(因此它依赖于给定这么多位的极小的冲突机会)而不是其他可以使用时间、mac 地址、pid 组合的方法, 或其他种类的时间 & space 标识符来保证唯一性。

相关规格见此处:https://www.rfc-editor.org/rfc/rfc4122#section-4.1.3