一千萬個為什麽

搜索

如何創建確定性指導

在我們的應用程序中,我們使用具有Guid值的屬性創建Xml文件。該值必須在文件升級之間保持一致。因此,即使文件中的其他所有內容都發生更改,該屬性的guid值也應保持不變。

一個明顯的解決方案是創建一個靜態字典,其中包含文件名和用於它們的Guids。然後每當我們生成文件時,我們都會在字典中查找文件名並使用相應的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)。

轉載註明原文: 如何創建確定性指導