有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 哈希值?
最佳答案
与比特币相关的字节操作有点棘手,因为它们往往会随心所欲地切换字节顺序。首先,我们取初始的 []byte 数组表示
00000001c570c4764aadb3f09895619f549000b8b51a789e7f58ea750000709700000000103ca064f8c76c390683f8203043e91466a7fcc40e6ebc428fbcc2d89b574a864db8345b1b00b5ac00000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000
然后,我们分离出数组的前半部分,得到:
00000001c570c4764aadb3f09895619f549000b8b51a789e7f58ea750000709700000000103ca06 4f8c76c390683f8203043e91466a7fcc40e6ebc428fbcc2d8
之后,我们需要交换一些字节。我们将每4字节的 slice 中的字节顺序倒过来,从而得到:
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 字节的 slice 中交换一点字节,我们将拥有比特币矿池和矿工使用的正确“中间状态”(直到不再需要它,因为它是已弃用)。
关于hash - Go, midstate SHA-256 哈希,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9245235/