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