Golang随机Sha256

4
我在使用时间戳种子生成随机sha256哈希时遇到了问题: https://play.golang.org/p/2-_VPe3oFr(不要使用playground - 时间始终相同)
有人知道为什么它总是返回相同的结果吗?(非playground运行)

1
请发布您的代码。(play.golang.org的链接可以,但它不能替代代码本身。) - ruakh
2
你为什么想要一个“随机的sha256哈希”?sha256哈希不是随机的;它是其输入的确定性函数。如果你需要的是一个随机的256位序列,为什么要涉及sha256呢? - Keith Thompson
2个回答

13

因为你做了这件事:

timestamp := time.Now().Unix()
log.Print(fmt.Sprintf("%x", sha256.Sum256([]byte(string(timestamp))))[:45])

您打印数据的SHA-256摘要的十六进制形式:

[]byte(string(timestamp))

这是什么?

timestamp 的类型是 int64,将其转换为字符串的方法如下:

将有符号或无符号整数值转换为字符串类型会产生一个字符串,其中包含该整数的UTF-8表示。 超出有效Unicode代码点范围的值将被转换为“\uFFFD”。

但它的值不是有效的Unicode代码点,因此它将始终为"\uFFFD",即efbfbd(UTF-8编码),您的代码始终打印数据[]byte{0xef, 0xbf, 0xbd}的SHA-256,这是其前45个十六进制数字(因为您切片了结果):

83d544ccc223c057d2bf80d3f2a32982c32c3c0db8e26

我猜您想要生成一些随机字节并计算SHA-256,就像这样:

data := make([]byte, 10)
for i := range data {
    data[i] = byte(rand.Intn(256))
}
fmt.Printf("%x", sha256.Sum256(data))

请注意,如果您使用 crypto/rand 包而不是 math/rand,则可以使用 rand.Read() 函数填充字节切片以获取随机值,甚至无需设置种子(因此无需使用 time 包):

data := make([]byte, 10)
if _, err := rand.Read(data); err == nil {
    fmt.Printf("%x", sha256.Sum256(data))
}

4
是的。这个:
string(timestamp)

这段代码并不是你想象中的那样,详见规范。简而言之,时间戳不是有效的Unicode码点,因此结果总是"\uFFFD"。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接