一尘不染

如何创建确定性指南

c#

在我们的应用程序中,我们正在创建具有Guid值的属性的Xml文件。此值需要在文件升级之间保持一致。因此,即使文件中的所有其他内容都发生变化,该属性的guid值也应保持不变。

一种明显的解决方案是使用文件名和要使用的Guid创建静态字典。然后,无论何时生成文件,我们都会在字典中查找文件名并使用相应的guid。但这是不可行的,因为我们可能会扩展到100个文件,并且不想维护大量的Guid。

因此,另一种方法是根据文件的路径使Guid相同。由于我们的文件路径和应用程序目录结构是唯一的,因此Guid对于该路径应该是唯一的。因此,每次我们运行升级时,文件都会根据其路径获得相同的GUID。我找到了一种生成此类“
确定性指南
”的不错方法(谢谢Elton Stoneman)。它基本上是这样做的:

private Guid GetDeterministicGuid(string input)

{

//use MD5 hash to get a 16-byte hash of the string:

MD5CryptoServiceProvider provider = new MD5CryptoServiceProvider();

byte[] inputBytes = Encoding.Default.GetBytes(input);

byte[] hashBytes = provider.ComputeHash(inputBytes);

//generate a guid from the hash:

Guid hashGuid = new Guid(hashBytes);

return hashGuid;

}

因此,给定一个字符串,Guid将始终相同。

还有其他方法或建议的方法吗?该方法的优缺点是什么?


阅读 212

收藏
2020-05-19

共1个答案

一尘不染

如@bacar所述,RFC 4122§4.3
定义了一种创建基于名称的UUID的方法。这样做的好处(仅使用MD5哈希)是确保它们不会与非基于名称的UUID冲突,并且与其他基于名称的UUID发生冲突的可能性非常小。

.NET
Framework没有用于创建这些功能的本机支持,但我在GitHub上发布了实现该算法的代码。可以如下使用:

Guid guid = GuidUtility.Create(GuidUtility.UrlNamespace, filePath);

为了进一步降低与其他GUID发生冲突的风险,您可以创建一个私有GUID用作名称空间ID(而不是使用RFC中定义的URL名称空间ID)。

2020-05-19