從Git Tip of the Week: Objects一文中得知,Git是這樣計算提交內容的Hash值的:
Hash算法用的是SHA1
計算前,會在內容前面添加"blob 內容長度\0",\0表示的是空字符(NUL)。
計算出來的Hash值是40位16進制序列(40-character hexadecimal sequence)。
比如提交一個空文件,Git計算出來的Hash值是e69de29bb2d1d6434b8b29ae775ad8c2e48c5391,實際計算的內容是"blob 0\0"。
在Mac的Terminal中輸入命令:echo -en "blob 0\0" | shasum,計算出來也是同樣的Hash值。
那在C#中如何以同樣的方法計算Hash值呢?
SHA1 Hash算法——C#中對應的實現是SHA1Managed。
和Git一樣在內容前面添加字符串——string.Format("blob {0}\0{1}", Content.Length, Content);
生成40位16進制的Hash值——ToString("x2")。
具體實現代碼如下:
public class Autosave { public string Content { get; set; } public string Hash { get; set; } public void GenerateHash() { var computedContent = string.Format("blob {0}\0{1}", Content.Length, Content); var hashBytes = new SHA1Managed().ComputeHash(Encoding.UTF8.GetBytes(computedContent)); var sb = new StringBuilder(); for (int i = 0; i < hashBytes.Length; i++) { sb.Append(hashBytes[i].ToString("x2")); } this.Hash = sb.ToString(); } }
測試代碼如下:
public class AutosaveTest { [Fact] public void GenerateHash_Test() { var autosave = new Autosave(); autosave.Content = ""; autosave.GenerateHash(); Assert.Equal("e69de29bb2d1d6434b8b29ae775ad8c2e48c5391", autosave.Hash); } }
測試結果:
1 passed, 0 failed, 0 skipped, took 1.13 seconds (xUnit.net 1.9.2 build 1705).
搞定!
本文URL地址:http://www.bianceng.cn/Programming/csharp/201410/45474.htm