hash - Go, midstate SHA-256 哈希

标签 hash go state sha256 sha

有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
}

其中 Uint322Hexuint32 变量转换为 []byte 变量。拥有所有这些,我们可以调用:

var h BitSHA.Hash = BitSHA.New()
h.Write(Str2Hex("0100000076C470C5F0B3AD4A9F619598B80090549E781AB575EA587F977000000000000064A03C10396CC7F820F8830614E94330C4FCA76642BC6E0ED8C2BC8F"))
log.Printf("%X", h.Midstate())

其中 Str2Hexstring 转换为 []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/

相关文章:

c++ - 是否存在满足以下条件的哈希函数

json - Golang解码数组给出运行时错误: index out of range

go - 在 golang 中正确映射 YAML 配置文件

javascript - 在不同的按钮中调用相同的函数,并且两者都在 Reactjs、javascript 中给出不同的输出?

javascript - 如何更新对象的 react 状态数组

javascript - ReactJS:更改子组件的状态

ruby - 检查散列是否有一个包含一些文本的键

c# - 在 C# 中散列委托(delegate)函数

algorithm - FNV-1A 哈希 - 一次异或 4 个字节

go - 删除 slice 中的元素导致原始 slice 发生变化?