英文:
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。)
英文:
(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 < 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.)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论