Golang随机Sha256

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

Golang Random Sha256

问题

我在使用时间戳种子生成随机的SHA256哈希值时遇到了问题:

https://play.golang.org/p/2-_VPe3oFr(不要使用playground,因为时间戳总是相同的)

有人知道为什么它总是返回相同的结果吗?(非playground运行)

英文:

I am having trouble getting a random sha256 hash using a timestamp seed:

https://play.golang.org/p/2-_VPe3oFr (dont use playground - time always same)

Does anyone understand why it always returns the same result? (non-playground runs)

答案1

得分: 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))
}
英文:

Because you do this:

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

You print the hex form of the SHA-256 digest of the data:

[]byte(string(timestamp))

What is it exactly?

timestamp is of type int64, converting it to string is:

> Converting a signed or unsigned integer value to a string type yields a string containing the UTF-8 representation of the integer. Values outside the range of valid Unicode code points are converted to "\uFFFD".

But its value is not a valid unicode code point so it will always be "\uFFFD" which is efbfbd (UTF-8 encoded), and your code always prints the SHA-256 of the data []byte{0xef, 0xbf, 0xbd} which is (or rather its first 45 hex digits because you slice the result):

83d544ccc223c057d2bf80d3f2a32982c32c3c0db8e26

I guess you wanted to generate some random bytes and calculate the SHA-256 of that, something like this:

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

Note that if you'd use the crypto/rand package instead of math/rand, you could fill a slice of bytes with random values using the rand.Read() function, and you don't even have to set seed (and so you don't even need the time package):

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

答案2

得分: 4

是的。这个代码:

string(timestamp)

并不是你想象中的那样,详见规范。简而言之,时间戳不是一个有效的 Unicode 代码点,所以结果始终是"\uFFFD"。

英文:

Yes. This:

string(timestamp)

does not do what you think it does, see the spec. Long story short, the timestamp is not a valid unicode code point, so the result is always "\uFFFD".

huangapple
  • 本文由 发表于 2015年3月9日 08:45:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/28933687.html
匿名

发表评论

匿名网友

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

确定