【问题标题】:How to convert an sha3 hash to an big integer in golang如何在golang中将sha3哈希转换为大整数
【发布时间】:2021-08-09 15:22:02
【问题描述】:

我使用 sha3 生成了一个哈希值,我需要将其转换为 big.Int 值。可能吗 ?或者有没有办法获取哈希的整数值?

以下代码抛出一个错误,无法将类型 hash.Hash 转换为 int64 类型:

package main 

import (
"math/big"
"golang.org/x/crypto/sha3"
"fmt"

)
func main(){

  chall := "hello word"
  b := byte[](chall)
  h := sha3.New244()
  h.Write(chall)
  h.Write(b)
  d := make([]byte, 16)
  h.Sum(d)
  val := big.NewInt(int64(h))
  fmt.Println(val)

}


【问题讨论】:

  • 你认为28字节的“整数值”是什么?
  • 您能否澄清您的问题。你想保存哈希的状态 - 还是只是它的总和?正如@Volker 提到的,224(位)散列 - 太大而无法放入 64 位。

标签: go type-conversion biginteger sha-3


【解决方案1】:

TL;DR;

sha3.New224() 不能用 uint64 类型表示。


有许多散列类型 - 并且大小不一。 Go 标准库选择了一个非常通用的接口来涵盖所有类型的哈希:https://golang.org/pkg/hash/#Hash

type Hash interface {
    io.Writer
    Sum(b []byte) []byte
    Reset()
    Size() int
    BlockSize() int
}

话虽如此,一些 Go 哈希实现可以选择包含额外的方法,例如 hash.Hash64

type Hash64 interface {
    Hash
    Sum64() uint64
}

其他人可以实现encoding.BinaryMarshaler:

type BinaryMarshaler interface {
    MarshalBinary() (data []byte, err error)
}

可以用来保存哈希状态。

sha3.New224() 没有实现上述 2 个接口,但crc64 hash 实现了。 要进行运行时检查:

h64, ok := h.(hash.Hash64)
if ok {
    fmt.Printf("64-bit: %d\n", h64.Sum64())
}

工作示例:https://play.golang.org/p/uLUfw0gMZka

【讨论】:

    【解决方案2】:

    (请参阅 Peter 的评论以了解更简单的版本。)

    将一系列字节解释为big.Int 与将一系列十进制数字解释为任意大数相同。例如,要将数字 1234 转换为“数字”,您可以这样做:

    • 从 0 开始
    • 乘以 10 = 0
    • 加 1 = 1
    • 乘以 10 = 10
    • 加 2 = 12
    • 乘以 10 = 120
    • 加 3 = 123
    • 乘以 10 = 1230
    • 加 4 = 1234

    这同样适用于字节。 “数字”只是 base-256 而不是 base-10:

    val := big.NewInt(0)
    for i := 0; i < h.Size(); i++ {
        val.Lsh(val, 8)
        val.Add(val, big.NewInt(int64(d[i])))
    }
    

    Lsh是左移。左移8位相当于乘以256。)

    Playground

    【讨论】:

    • 这应该与val := new(big.Int).SetBytes(d) 相同。 "SetBytes interprets buf as the bytes of a big-endian unsigned integer."
    • @彼得哈哈哈;是的。我原以为有这样的方法,只是找不到它(我一直希望它在 New 函数而不是 Set 函数下)。谢谢你。您可以将此作为答案发布吗?
    • 如果散列的字节应该被解释为大端无符号,那么您(和彼得斯)的解决方案是正确的。 Litte-endian 或有符号(二进制补码或任何其他形式)或对该位模式的任何其他解释(例如,使用 popcount 作为值)将导致不同的值。
    猜你喜欢
    • 2013-04-22
    • 2015-11-26
    • 1970-01-01
    • 2017-11-05
    • 1970-01-01
    • 1970-01-01
    • 2019-10-27
    • 2019-05-23
    • 2012-11-11
    相关资源
    最近更新 更多