手动更改生成的 GUID 并使用它有多糟糕?碰撞的可能性仍然微不足道还是使用 GUID 进行操作是否危险?
有时我们只是更改之前生成的 GUID 的一些字母并使用它。我们应该停止这样做吗?
手动更改生成的 GUID 并使用它有多糟糕?碰撞的可能性仍然微不足道还是使用 GUID 进行操作是否危险?
有时我们只是更改之前生成的 GUID 的一些字母并使用它。我们应该停止这样做吗?
这取决于 GUID 的版本以及进行更改的位置。让我们稍微剖析一下 GUID 的实际外观:
GUID 有一个版本。 GUID 中的第 13 个十六进制数字标记其版本。当前的 GUID 通常是使用版本 4 生成的。如果向后更改版本,则可能会与已经存在的 GUID 发生冲突。向前更改它,您可能会与潜在的未来 GUID 发生冲突。
GUID 也有一个变体。 GUID 中的第 17 个十六进制数字是变量字段。它的一些值是为向后兼容而保留的,一个值是为将来的扩展而保留的。因此,在此处更改某些内容意味着您可能会与以前生成的 GUID 或将来生成的 GUID 发生冲突。
GUID 的结构因版本而异。 第 4 版 GUID 使用(在大多数情况下 - 除了第 17 个十六进制数字)真正随机或伪随机位(在大多数实现中是伪随机)。在那里改变一些东西,你的碰撞概率保持不变。
对于使用哈希的第 3 版和第 5 版 GUID,它应该非常相似,尽管我不记得曾经在野外看到过。不过,对于版本 1 和 2 而言,情况并非如此。那些有一个结构,根据你改变的地方,你会让事情变得困难。
版本 1 GUID 包括时间戳和计数器字段,如果在同一时钟间隔内生成两个 GUID(因此会导致相同的时间戳),则该字段会递增。如果更改时间戳,则可能会与同一台机器上早晚生成的 GUID 发生冲突。如果更改计数器,则可能会与同时生成的 GUID 发生冲突,因此需要将计数器作为“唯一性”。
第 2 版 GUID 在第 1 版的基础上扩展,还包括用户 ID。 时间戳不太准确,并且包含用户或组 ID,而计数器的一部分用于指示是哪一个(但仅对生成机器有意义)。因此,随着这些部分的更改,您可能会与同一台机器上的另一个用户生成的 GUID 发生冲突。
版本 1 和 2 GUID 包括 MAC 地址。 具体来说,生成它们的计算机的 MAC 地址。这确保了来自不同机器的 GUID 是不同的,即使是在同一时刻生成的。如果机器没有 MAC 地址但没有唯一性保证,则存在备用。MAC 地址也有一个结构,由“组织唯一标识符”(OUI;由本地管理或由 IEEE 分发)和网卡的唯一标识符组成。
如果您在 OUI 中进行更改,您可能会与使用其他制造商的网卡的计算机中生成的 GUID 发生冲突。除非您进行更改,使第一个八位字节的次低有效位为 1,在这种情况下,您将切换到本地管理的 OUI,并且只会冒与在具有覆盖 MAC 地址的计算机上生成的 GUID 发生冲突的风险(这可能包括大多数具有虚拟网络硬件的 VM)。
如果您偶然发现卡标识符,则可能会与同一制造商在具有其他网卡的计算机上生成的 GUID 发生冲突,或者再次与 MAC 地址被覆盖的那些计算机上生成的 GUID 发生冲突。
到目前为止还没有其他版本,但要点如下:GUID 需要其所有部分来确保唯一性;如果您更改某些内容,您最终可能会得到一个不一定是唯一的 GUID。所以你可能让它更像是一个 GID 或其他东西。最安全的更改可能是当前版本 4 GUID(这是 Windows 和 .NET 将生成的),因为它们并不能真正保证唯一性,而是使其非常非常不可能。
不过,通常我会说你最好生成一个新的 GUID。这也有助于阅读它们的人,因为如果它们看起来完全不同,您可以轻松地将两个 GUID 区分开来。如果它们仅在一个数字上有所不同,则人们可能会错过更改并假设 GUID 相同。
进一步阅读:
我不知道这会如何影响 GUID 的唯一性,但这可能不是一个好主意。
Visual Studio 有一个内置的 GUID 生成器,它需要几秒钟来启动并创建一个新的 GUID。如果您不使用 VS,那么还有其他简单的方法可以创建一个新的。此页面有 2 个脚本(VB 脚本和 PHP)可以完成这项工作,这是一个 .net 版本