.NET 4 GUID 是如何生成的?

发布于 2024-08-31 19:32:27 字数 542 浏览 2 评论 0 原文

我知道这里有很多问题这里以及雷蒙德的优秀问题(像往常一样)帖子。然而,由于创建 GUID 的算法明显发生了变化,我发现很难获得任何最新信息。 MSDN 似乎尝试提供尽可能少的信息。

关于 .NET 4 中如何生成 GUID,我们了解多少?更改了什么?它如何影响安全性(“随机性”)和完整性(“唯一性”)?

我感兴趣的一个具体方面:在 v1 中,似乎不可能在一台计算机上再次生成相同的 GUID,因为涉及时间戳和计数器。在 v4 中,情况不再如此(有人告诉我),因此在单台计算机上获得相同 GUID 的机会......增加了

I am aware of the multitude of questions here as well as Raymond's excellent (as usual) post. However, since the algorithm to create GUIDs was changed apparently, I found it hard to get my hands on any up-to-date information. The MSDN seems to try and provide as few information as possible.

What is known about how GUIDs are generated in .NET 4? What was changed, and how does it affect the security ("randomness") and integrity ("uniqueness")?

One specific aspect I'm interested in: In v1, it seems to be about impossible to generate the same GUID on a single machine again since there was a timestamp and counter involved. In v4, this is no longer the case (I was told), so the chance to get the same GUID on a single machine ... increased?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

不语却知心 2024-09-07 19:32:27

Windows 2000 起,Microsoft 使用版本 4 算法:

在 Windows 2000 中,Microsoft 切换到版本 4 GUID,因为嵌入 MAC 地址被视为安全风险。 1

您也可以从 .NET 中生成的 GUID 中看到这一点(来自 维基百科):

版本 4 UUID 的格式为 xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx,其中 x 可以是任何十六进制数字,但 yeg f47ac10b-58cc-4372-a567-0e02b2c3d479 只能是 8、9、A 或 B 之一。

版本 4 UUID 由 122 个有效位组成,提供 2^122 个不同的值,这是一个非常大的数字。给定一组 H 值,在以 50% 的概率找到第一次随机碰撞之前,我们必须选择的预期值数量可以计算如下(请参阅 维基百科上的生日攻击):

alt text

2^122 个不同值的结果(生日范围)约为 2,89e+18。这假设生成的值是随机分布的。显然,如果值分布不均匀,则可以更快地发现随机碰撞。有关更多详细信息,请参阅冲突

1事实上,Melissa 蠕虫病毒的作者可能是 由于使用版本 1 算法生成的 GUID 而被追踪

Since Windows 2000 Microsoft uses a version 4 algorithm:

With Windows 2000, Microsoft switched to version 4 GUIDs, since embedding the MAC address was viewed as a security risk. 1

You can see that as well from a GUID generated in .NET (from Wikipedia):

Version 4 UUIDs have the form xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx with any hexadecimal digits for x but only one of 8, 9, A, or B for y. e.g. f47ac10b-58cc-4372-a567-0e02b2c3d479.

A version 4 UUID consist of 122 significant bits, giving 2^122 distinct values which is a very large number. Given a set of H values, the expected number of values we have to choose before finding the first random collision with a 50% chance can be calculated as follows (see Birthday Attack on Wikipedia):

alt text

The result (birthday bound) for 2^122 different values is approximately 2,89e+18. This assumes that the generated values are randomly distributed. Obviously, if the values are distributed unevenly, a random collision can be found faster. For further details also see Collisions.

1As a matter of fact, the author of the Melissa worm could be tracked down due to a GUID generated using a version 1 algorithm.

来日方长 2024-09-07 19:32:27

是的,.NET 4.0 中发生了变化,Guid.NewGuid() 直接调用 CoCreateGuid(),UuidCreate() 的一个小包装。 .NET 的早期版本在 CLR 中调用了辅助函数 GuidNative::CompleteGuid()。其中调用 CoCreateGuid。不知道为什么要进行此更改,听起来只不过是一个小的优化。

无论如何,完全相同的 Windows 函数生成 Guid,算法在过去 10 年中一直相同,它一如既往地可靠。

Yes, there was a change in .NET 4.0, Guid.NewGuid() directly calls CoCreateGuid(), a small wrapper around UuidCreate(). Previous versions of .NET called a helper function in the CLR, GuidNative::CompleteGuid(). Which calls CoCreateGuid. Not sure why this change was made, smells like nothing more than a minor optimization.

At any rate, the exact same Windows function generates the Guid, the algorithm has been the same for the past 10 years, it is as reliable as it ever was.

枫以 2024-09-07 19:32:27

GUID 生成算法记录在 GUID 本身中,检查变体和(可选)版本。维基百科给出了一个很好的概述:首先,GUID 变体

变体由第 9 个八位字节的初始位指示,“固定”到 010110111 >。使用

string show(Guid g) => $"{g}: fam {Convert.ToString(g.ToByteArray()[8], 2)}";
show(Guid.NewGuid())

我们可能会得到“1b579ecd-b72c-4550-b10b-f8dd41699ac1:fam 10110001”。该系列固定为 10OSF DCE UUID变体 2。该变体定义了一个版本,保存在第 7 个八位位组的更重要的“半字节”中。

但是,变体 2 作为 MS 格式,是 little-endian。让我们看一下另一种快速方法:

void SeeOrder(Guid g) => Console.WriteLine($"{g}\n{g:N}\n{string.Join("", g.ToByteArray().Select(b => $"{b:x2}"))}"); 

显示类似的内容

dd3f9bdf-ba47-4411-84c8-6cfcc5d39bb5
dd3f9bdfba47441184c86cfcc5d39bb5
df9b3fdd47ba114484c86cfcc5d39bb5

前三个整数组已转置 - 两个表示时间,一个保留;分别为 32、16 和 16 位。最后两组不是,因为最后 8 个八位字节是一个“字符串”:1 个保留八位字节(表示“族”)和 7 个“节点”八位字节。因此,第 7 个版本的八位字节实际上被编码为第 8 个版本(索引 7)。

展开 show 以突出显示版本:

string show(Guid g) => $"{g}: fam {Convert.ToString(g.ToByteArray()[8], 2)}, ver {g.ToByteArray()[7].ToString("x")}";

我们将得到 "154573de-d420-433b-bb25-aff50590038b: fam 10111011, ver 43"。所讨论的半字节是4,因此是版本4:伪随机生成

The GUID generation algorithm is recorded in the GUID itself, checking the variant and (optionally) the version. Wikipedia gives a good rundown: first, GUID Variants.

Variant is indicated by the initial bits of the 9th octet, "pinned" to 0, 10, 110 or 111. Using

string show(Guid g) => 
quot;{g}: fam {Convert.ToString(g.ToByteArray()[8], 2)}";
show(Guid.NewGuid())

we might get "1b579ecd-b72c-4550-b10b-f8dd41699ac1: fam 10110001". The family is pinned to 10, OSF DCE UUID or variant 2. This variant defines a version, held in the more significant "nibble" of the 7th octet.

BUT, variant 2, being an MS format is little-endian. Let's take a look with another quick method:

void SeeOrder(Guid g) => Console.WriteLine(
quot;{g}\n{g:N}\n{string.Join("", g.ToByteArray().Select(b => 
quot;{b:x2}"))}"); 

shows something like

dd3f9bdf-ba47-4411-84c8-6cfcc5d39bb5
dd3f9bdfba47441184c86cfcc5d39bb5
df9b3fdd47ba114484c86cfcc5d39bb5

The first three integer groups are transposed—two for time, one reserved; 32, 16 and 16 bits respectively. The last two groups are not, because the last 8 octets are a "string": 1 reserved octet (where the "family" is represented) and 7 "node" octets. So the 7th version octet is actually encoded as the 8th (index 7).

Expanding show to highlight the version:

string show(Guid g) => 
quot;{g}: fam {Convert.ToString(g.ToByteArray()[8], 2)}, ver {g.ToByteArray()[7].ToString("x")}";

We'll get "154573de-d420-433b-bb25-aff50590038b: fam 10111011, ver 43". The nibble in question is the 4, thus version 4: pseudo-random generation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文