Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Hash 去,中州SHA-256散列_Hash_Go_State_Sha256_Sha - Fatal编程技术网

Hash 去,中州SHA-256散列

Hash 去,中州SHA-256散列,hash,go,state,sha256,sha,Hash,Go,State,Sha256,Sha,具有128字节的数据,例如: 00000001c570c4764aadb3f09895619f549000b8b51a789e7f58ea750000709700000000103ca064f8c76c390683f8203043e91466a7fcc40e6ebc428fbcc2d89b574a864db8345b1b00b5ac00000000000000800000000000000000000000000000000000000000000000000000000000000000000

具有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
我得到

在讨论这件事时,有人提到获取中间状态哈希可能会有一些问题


如何在Google Go中计算中间状态SHA-256哈希?

您的Go代码是计算字节流sha256的正确方法

最有可能的答案是,你想做的不是什么。具体而言:

在将结果散列到一起之前,必须将其分离为两个64位的数据并分别散列。如果要经常更改数据后半部分中的某些位,可以简化计算并只对数据前半部分进行一次散列

不是计算sha256的有效方法(读取以查看sha256在数据块上执行其工作,必须对数据块进行填充等)

您描述的算法计算某些东西,但不是sha256

因为您知道预期值,所以您可能有一些其他语言的算法参考实现,所以只需执行一行接一行的端口即可

最后,无论如何,这是一个可疑的优化。128位是16字节。散列开销通常与数据的大小成正比。16字节的成本非常小,因此,通过将数据拆分为8字节部分来提高智能的额外工作的成本可能比您节省的成本更高。

在函数
Sum()
的开头,实现正在复制SHA256状态。SHA256的底层数据类型(struct
digest
)是SHA256包的私有数据类型

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

func (d *digest) Copy() hash.Hash {
    d_copy := *d
    return &d_copy
}

然后只需调用
Copy()
函数来保存中间状态SHA256哈希。

我使用Intel i5 2.70 GHz CPU对128字节的数据运行了两个Go基准测试。首先,1000次,我将所有128字节写入SHA256散列并读取总和,总共花费了9285000纳秒。其次,我将前64个字节写入SHA256散列一次,然后,我将第二个64字节写入SHA256散列的副本并读取总和,总共花费了大约6492371纳秒。第二个基准测试假设前64个字节不变,运行时间比第一个基准测试少30%

使用第一种方法,在购买更快的CPU之前,您可以每天计算大约9305331179个SHA256 128字节的总和。使用第二种方法,在购买更快的CPU之前,您可以计算每天1330792713 SHA256 128字节的总和,假设前64个字节是连续1000次不变的。每天需要计算多少个SHA256 128字节和?对于每天有多少个SHA256 128字节和,前64个字节是不变的


您运行了哪些基准测试,结果如何?

比特币相关的字节操作有点棘手,因为它们往往会一时兴起地切换endianness。首先,我们取初始[]字节数组,表示

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

00000001c570c4764aadb3f09895619f549000b8b51a789e7f58ea750000709700000000103ca06 4f8c76c390683f8203043e91466a7fcc40e6ebc428fbcc2d8
0100000076C470C5F0B3AD4A9F619598B80090549E781AB575EA587F977000000000000064A03C10396CC7F820F8830614E94330C4FCA76642BC6E0ED8C2BC8F
之后,我们需要交换一些字节。我们将4个字节的每个片段中的字节顺序颠倒,从而获得:

00000001c570c4764aadb3f09895619f549000b8b51a789e7f58ea750000709700000000103ca06 4f8c76c390683f8203043e91466a7fcc40e6ebc428fbcc2d8
0100000076C470C5F0B3AD4A9F619598B80090549E781AB575EA587F977000000000000064A03C10396CC7F820F8830614E94330C4FCA76642BC6E0ED8C2BC8F
这就是我们用来计算中间状态的数组。现在,我们需要修改文件
hash.go
,将其添加到
类型hash接口中

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
}
其中
Str2Hex
字符串
转换为
[]字节
。结果是:

69FC72E76DB0E764615A858F483E3566E42D56B2BC7A03ADCE9492887010EDA8
记住正确的答案:

e772fc6964e7b06d8f855a6166353e48b2562de4ad037abc889294cea8ed1070
我们可以比较:

69FC72E7 6DB0E764 615A858F 483E3566 E42D56B2 BC7A03AD CE949288 7010EDA8
e772fc69 64e7b06d 8f855a61 66353e48 b2562de4 ad037abc 889294ce a8ed1070

因此,我们可以看到,我们只需要在4个字节的每个片段中交换一位左右的字节,就可以得到比特币池和挖掘者使用的适当的“中间状态”(直到由于不推荐使用而不再需要它)。

对不起,我指的是字节,而不是位。使用这些数据的实现只是为了将数据散列在一起,改变字符串的后半部分,因此计算中间状态可以节省相当大的计算任务。对我来说,64字节对128字节是无关紧要的,特别是考虑到sha256的工作方式。Sha256在最小56字节的块上运行。您不希望在128字节上执行顺序sha256,而是希望在64字节(填充为2*56,即112)上执行该操作,以获得一半数据的sha256,再加上32+32(32是sha256校验和的大小),再加上设置额外sha256进程的开销。事实上,在128字节上做应该会更快(而且结果并不相同)。通常,该实现与比特币挖掘相关,特别是与getwork协议相关(也在链接主题中解释)。如果在客户端使用,并且支持Go的OpenCL,操作顺序可能是每秒10^9次哈希(如果达到当前使用的挖掘软件的速度)-实际上,还需要更改hash.Go文件以更改hash.hash接口以允许调用Copy(),但即使在这之后,我也会得到[BE7E1F35 A19D5938 D8E6A17B 6BDF4738 603BB417 9AE97BCE FAED662 C11CB2F7].好的,让我们看看…比特币的尾端有点棘手,在输入输入到SHA函数之前,有很多奇怪的字节交换正在进行。最后,这个经过一些修改的解决方案会起作用。你介意详细说明一下你是如何从
010000076C470C5F0B3AD4A9F6195开始的吗