我正在尝试手动获取GIT提交的SHA1提交哈希值,但某些内容无法正常工作。
首先,我们有标准的提交消息,如下所示:
tree f594b3f6d9ae291c83902f3992aa36872aa70d68
parent 0000004bf6d464667df5150b4526083886947d92
author User <foo@bar.com> 1390620460.46263 +0000
committer User <foo@bar.com> 1390620460.46263 +0000
Commit Message
我们称之为'commitMessage'
规范说要获取提交哈希说我们必须使用sha1:
so(伪代码obv)
SHA1( "commit" + " " + numBytes(commitMessage) + '\0' + commitMessage );
这是我在C#中的实现 (我知道这很笨重)
var commitBody = "tree " + treeHash + "\n\n" +
"parent " + parentHash + "\n\n" +
"author User <foo@bar.com> " + date + "\n" +
"committer User <foo@bar.com> " + date + "\n\n" +
"My Commit Message\n";
var blob = "commit " + Encoding.UTF8.GetByteCount(commitBody);
// This is the string "commit " (with a space) + byte count
var first = Encoding.UTF8.GetBytes(blob);
// This is just the null byte
var second = new byte[1];
second[0] = (byte)0;
// This is the commitMessage
var third = Encoding.UTF8.GetBytes(commitBody);
// Merge first, second, third into bytez as a byte array
var bytez = new byte[first.Length + second.Length + third.Length];
Buffer.BlockCopy(first, 0, bytez, 0, first.Length);
Buffer.BlockCopy(second, 0, bytez, first.Length, second.Length);
Buffer.BlockCopy(third, 0, bytez, first.Length + second.Length, third.Length);
// Debug Print
Console.WriteLine(Encoding.UTF8.GetString(bytez));
// Compute the hash and print it
var sss = SHA1.Create();
var myssh = GetString(sss.ComputeHash(bytez));
Console.WriteLine(myssh);
返回的哈希值与GIT返回的哈希值不同。我实际上并不希望任何人知道如何做到这一点,因为这不是通常做的事情,但我想我会问。
感谢您的帮助:D
答案 0 :(得分:1)
每个对象的哈希实际上都是“长度+'+ +内容”的哈希值 - 这可以防止SHA1哈希冲突(因为现在你必须在SHA1 和两者上发生冲突,是不太可能)
答案 1 :(得分:1)
如果在字符串中使用UTF-8字符,请不要使用string.Length
来保留字节数组。如果字符串仅包含ASCII字符,但如果字符串中包含UTF-8字符,那么.Length
将小于实际字节大小。
由于您使用.Length
来分配数组,因此该数组可能很小,并且不会复制所有字符串数据。
我建议您使用StringBuilder
构建字符串,然后使用System.Text.Encoding.UTF8.GetBytes(stringbuilder.ToString())
将数据作为字节获取。
StringBuilder sb = new StringBuilder();
sb.Append("commit "+ Encoding.UTF8.GetByteCount(commitBody));
sb.Append("\0");
sb.Append(commitBody);
var sss = SHA1.Create();
var bytez = Encoding.UTF8.GetBytes(sb.ToString());
var myssh = GetString(sss.ComputeHash(bytez));
Console.WriteLine(myssh);
答案 2 :(得分:0)
tree
和parent
行之后应该没有空行,即提交正文应该是:
tree f594b3f6d9ae291c83902f3992aa36872aa70d68
parent 0000004bf6d464667df5150b4526083886947d92
author User <foo@bar.com> 1390620460.46263 +0000
committer User <foo@bar.com> 1390620460.46263 +0000
Commit Message
参见原始的C实现; commit.c中的commit_tree_extended()。
答案 3 :(得分:0)
不是C#,但是这里有如何从bash提示符计算git commit hash:
keyup
检查哈希是否正确:
<input type="text" id="searchbar" placeholder="search file"> <span id="loading" style="display:none;">loading</span>
<div id="result"></div>
<script src="../../vendor/jquery/jquery-3.2.1.min.js"></script>
<script>
$(function(){
$('#searchbar').keyup(function(){//event after user release keyboard
var val = $(this).val();
if(val.length >= 2){//min 2 words to start find
$.ajax({
url: 'search.php',
type: 'POST',
dataType: 'json', //we use json
data: {keyword: val},
beforeSend: function(){
$('#loading').show();
},
success: function(d){
if(d.ok==1){
$('#result').html(d.list);
}else{
alert(d.msg);
}
$('#loading').hide();
},
error: function(d){
alert('error');
$('#loading').hide();
}
});
}
})
});
</script>