在我们的应用程序中,我们正在创建具有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将始终相同。
还有其他方法或建议的方法吗?该方法的优缺点是什么?
如@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)。