如何在Golang中将SHA3哈希转换为大整数?

huangapple go评论83阅读模式
英文:

How to convert an sha3 hash to an big integer in golang

问题

我使用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)
}
英文:

I generated a hash value using sha3 and I need to convert it to a big.Int value. Is it possible ? or is there a method to get the integervalue of the hash ?

the following code throws an error that cannot convert type hash.Hash to type 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)

}


答案1

得分: 2

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() 并没有实现上述两个接口,但 crc64 哈希实现了。
要进行运行时检查:

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

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

英文:

TL;DR;

sha3.New224() cannot be represented in uint64 type.


There are many hash types - and of differing sizes. Go standard library picks a very generic interface to cover all type of hashes: https://golang.org/pkg/hash/#Hash

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

Having said that some Go hash implementations optionally include extra methods like hash.Hash64:

type Hash64 interface {
    Hash
    Sum64() uint64
}

others may implement encoding.BinaryMarshaler:

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

which one can use to preserve a hash state.

sha3.New224() does not implement the above 2 interfaces, but crc64 hash does.
To do a runtime check:

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

Working example: https://play.golang.org/p/uLUfw0gMZka

答案2

得分: 0

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

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

对于字节也是一样的。这些"数字"只是基于256进制而不是基于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

英文:

(See Peter's comment for the simpler version of this.)

Interpreting a series of bytes as a big.Int is the same as interpreting a series of decimal digits as an arbitrarily large number. For example, to convert the digits 1234 into a "number", you'd do this:

  • Start with 0
  • Multiply by 10 = 0
  • Add 1 = 1
  • Multiply by 10 = 10
  • Add 2 = 12
  • Multiply by 10 = 120
  • Add 3 = 123
  • Multiply by 10 = 1230
  • Add 4 = 1234

The same applies to bytes. The "digits" are just base-256 rather than base-10:

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

(Lsh is a left-shift. Left shifting by 8 bits is the same as multiplying by 256.)

Playground

huangapple
  • 本文由 发表于 2021年5月20日 19:13:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/67619238.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定