ty9919 发表于 2018-1-16 10:59:54

C#实现像Git那样计算Hash值

  从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>
{  

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.ToString(
"x2"));  
}
  

this.Hash = sb.ToString();  
}
  
}
  

  测试代码如下:
  

public>
{  

  

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).  

  搞定!
页: [1]
查看完整版本: C#实现像Git那样计算Hash值