首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Go,中州SHA-256散列

Go,中州SHA-256散列
EN

Stack Overflow用户
提问于 2012-02-12 08:11:15
回答 4查看 6.2K关注 0票数 4

具有128字节的数据,例如:

代码语言:javascript
复制
00000001c570c4764aadb3f09895619f549000b8b51a789e7f58ea750000709700000000103ca064f8c76c390683f8203043e91466a7fcc40e6ebc428fbcc2d89b574a864db8345b1b00b5ac00000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000

想要对其执行SHA-256散列,必须将其分成两个64字节的数据,并在将结果散列在一起之前分别对它们进行散列。如果要经常更改数据后半部分中的一些位,则可以简化计算并仅对前半部分数据进行散列一次。如何在Google Go中做到这一点?我试着给你打电话

代码语言:javascript
复制
func SingleSHA(b []byte)([]byte){
    var h hash.Hash = sha256.New()
    h.Write(b)
    return h.Sum()
}

但不是正确的答案

代码语言:javascript
复制
e772fc6964e7b06d8f855a6166353e48b2562de4ad037abc889294cea8ed1070

我得到了

代码语言:javascript
复制
12E84A43CBC7689AE9916A30E1AA0F3CA12146CBF886B60103AEC21A5CFAA268

当在Bitcoin forum上讨论这个问题时,有人提到在获取中间状态散列时可能会有一些问题。

如何在Google Go中计算中州SHA-256散列?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-02-17 11:32:40

与比特币相关的字节操作有点棘手,因为它们往往会随心所欲地切换字节顺序。首先,我们使用初始的[]字节数组来表示

代码语言:javascript
复制
00000001c570c4764aadb3f09895619f549000b8b51a789e7f58ea750000709700000000103ca064f8c76c390683f8203043e91466a7fcc40e6ebc428fbcc2d89b574a864db8345b1b00b5ac00000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000

然后,我们分离出数组的前半部分,获得:

代码语言:javascript
复制
00000001c570c4764aadb3f09895619f549000b8b51a789e7f58ea750000709700000000103ca06 4f8c76c390683f8203043e91466a7fcc40e6ebc428fbcc2d8

在那之后,我们需要交换一些字节。我们在每个4字节的切片中颠倒字节的顺序,从而获得:

代码语言:javascript
复制
0100000076C470C5F0B3AD4A9F619598B80090549E781AB575EA587F977000000000000064A03C10396CC7F820F8830614E94330C4FCA76642BC6E0ED8C2BC8F

这就是我们要用来计算中间状态的数组。现在,我们需要修改文件hash.go,添加到type Hash interface

代码语言:javascript
复制
Midstate() []byte

并更改文件sha256.go,添加以下函数:

代码语言:javascript
复制
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变量。有了所有这些,我们可以调用:

代码语言:javascript
复制
var h BitSHA.Hash = BitSHA.New()
h.Write(Str2Hex("0100000076C470C5F0B3AD4A9F619598B80090549E781AB575EA587F977000000000000064A03C10396CC7F820F8830614E94330C4FCA76642BC6E0ED8C2BC8F"))
log.Printf("%X", h.Midstate())

其中Str2Hexstring转换为[]byte。结果是:

代码语言:javascript
复制
69FC72E76DB0E764615A858F483E3566E42D56B2BC7A03ADCE9492887010EDA8

记住正确的答案:

代码语言:javascript
复制
e772fc6964e7b06d8f855a6166353e48b2562de4ad037abc889294cea8ed1070

我们可以对它们进行比较:

代码语言:javascript
复制
69FC72E7 6DB0E764 615A858F 483E3566 E42D56B2 BC7A03AD CE949288 7010EDA8
e772fc69 64e7b06d 8f855a61 66353e48 b2562de4 ad037abc 889294ce a8ed1070

所以我们可以看到,我们只需要在每个4字节的切片中交换一位字节,我们将拥有比特币池和矿工使用的适当的“中间状态”(直到由于被弃用而不再需要它)。

票数 6
EN

Stack Overflow用户

发布于 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字节部分来变得更聪明的额外工作可能会比您节省的成本更高。

票数 3
EN

Stack Overflow用户

发布于 2012-02-12 19:39:05

sha256.go中,在函数Sum()的开头,实现是复制SHA256状态。SHA256 (结构digest)的底层数据类型是sha256包专用的。

我建议制作您自己的sha256.go文件的私有副本(它是一个小文件)。然后添加一个Copy()函数来保存摘要的当前状态:

代码语言:javascript
复制
func (d *digest) Copy() hash.Hash {
    d_copy := *d
    return &d_copy
}

然后,只需调用Copy()函数来保存中态SHA256散列。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9245235

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档