具有128字节的数据,例如:
00000001c570c4764aadb3f09895619f549000b8b51a789e7f58ea750000709700000000103ca064f8c76c390683f8203043e91466a7fcc40e6ebc428fbcc2d89b574a864db8345b1b00b5ac00000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000想要对其执行SHA-256散列,必须将其分成两个64字节的数据,并在将结果散列在一起之前分别对它们进行散列。如果要经常更改数据后半部分中的一些位,则可以简化计算并仅对前半部分数据进行散列一次。如何在Google Go中做到这一点?我试着给你打电话
func SingleSHA(b []byte)([]byte){
var h hash.Hash = sha256.New()
h.Write(b)
return h.Sum()
}但不是正确的答案
e772fc6964e7b06d8f855a6166353e48b2562de4ad037abc889294cea8ed1070我得到了
12E84A43CBC7689AE9916A30E1AA0F3CA12146CBF886B60103AEC21A5CFAA268当在Bitcoin forum上讨论这个问题时,有人提到在获取中间状态散列时可能会有一些问题。
如何在Google Go中计算中州SHA-256散列?
发布于 2012-02-17 11:32:40
与比特币相关的字节操作有点棘手,因为它们往往会随心所欲地切换字节顺序。首先,我们使用初始的[]字节数组来表示
00000001c570c4764aadb3f09895619f549000b8b51a789e7f58ea750000709700000000103ca064f8c76c390683f8203043e91466a7fcc40e6ebc428fbcc2d89b574a864db8345b1b00b5ac00000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000然后,我们分离出数组的前半部分,获得:
00000001c570c4764aadb3f09895619f549000b8b51a789e7f58ea750000709700000000103ca06 4f8c76c390683f8203043e91466a7fcc40e6ebc428fbcc2d8在那之后,我们需要交换一些字节。我们在每个4字节的切片中颠倒字节的顺序,从而获得:
0100000076C470C5F0B3AD4A9F619598B80090549E781AB575EA587F977000000000000064A03C10396CC7F820F8830614E94330C4FCA76642BC6E0ED8C2BC8F这就是我们要用来计算中间状态的数组。现在,我们需要修改文件hash.go,添加到type Hash interface
Midstate() []byte并更改文件sha256.go,添加以下函数:
func (d *digest) Midstate() []byte {
var answer []byte
for i:=0;i<len(d.h);i++{
answer=append(answer[:], Uint322Hex(d.h[i])...)
}
return answer
}其中Uint322Hex将uint32变量转换为[]byte变量。有了所有这些,我们可以调用:
var h BitSHA.Hash = BitSHA.New()
h.Write(Str2Hex("0100000076C470C5F0B3AD4A9F619598B80090549E781AB575EA587F977000000000000064A03C10396CC7F820F8830614E94330C4FCA76642BC6E0ED8C2BC8F"))
log.Printf("%X", h.Midstate())其中Str2Hex将string转换为[]byte。结果是:
69FC72E76DB0E764615A858F483E3566E42D56B2BC7A03ADCE9492887010EDA8记住正确的答案:
e772fc6964e7b06d8f855a6166353e48b2562de4ad037abc889294cea8ed1070我们可以对它们进行比较:
69FC72E7 6DB0E764 615A858F 483E3566 E42D56B2 BC7A03AD CE949288 7010EDA8
e772fc69 64e7b06d 8f855a61 66353e48 b2562de4 ad037abc 889294ce a8ed1070所以我们可以看到,我们只需要在每个4字节的切片中交换一位字节,我们将拥有比特币池和矿工使用的适当的“中间状态”(直到由于被弃用而不再需要它)。
发布于 2012-02-12 09:55:38
Go代码是计算字节流sha256的正确方法。
答案很可能是你想做的不是sha256。具体地说:
one必须将其分成两个64位的数据,并在将结果散列在一起之前分别对它们进行散列。如果要经常更改数据后半部分中的一些位,则可以简化计算并仅对前半部分数据进行散列一次。
不是计算sha256的有效方法(请阅读http://doc.golang.org/src/pkg/crypto/sha256/sha256.go以查看sha256是否对数据块起作用,这些数据块必须进行填充等)。
您描述的算法会计算一些东西,但不会计算sha256。
既然您知道期望值,那么您可能在另一种语言中对您的算法有一些参考实现,所以只需逐行执行端口。
最后,在任何情况下,这都是一个可疑的优化。128位是16字节。散列开销通常与数据大小成正比。对于16字节,成本是如此之小,以至于试图通过将数据拆分成8字节部分来变得更聪明的额外工作可能会比您节省的成本更高。
发布于 2012-02-12 19:39:05
在sha256.go中,在函数Sum()的开头,实现是复制SHA256状态。SHA256 (结构digest)的底层数据类型是sha256包专用的。
我建议制作您自己的sha256.go文件的私有副本(它是一个小文件)。然后添加一个Copy()函数来保存摘要的当前状态:
func (d *digest) Copy() hash.Hash {
d_copy := *d
return &d_copy
}然后,只需调用Copy()函数来保存中态SHA256散列。
https://stackoverflow.com/questions/9245235
复制相似问题