【发布时间】:2015-09-03 07:56:16
【问题描述】:
假设我想生成一个介于 0 到 27 之间的安全随机整数:
func Int(rand io.Reader, max *big.Int) (n *big.Int, err error)
在"crypto/rand" 包中。
我该怎么做?
我不太明白这是如何工作的,为什么它不返回内置的 Go 整数之一而不是指向某个 big.Int 类型的指针?
编辑:
这对于令牌来说是否足够安全?
func getToken(length int) string {
token := ""
codeAlphabet := "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
codeAlphabet += "abcdefghijklmnopqrstuvwxyz"
codeAlphabet += "0123456789"
for i := 0; i < length; i++ {
token += string(codeAlphabet[cryptoRandSecure(int64(len(codeAlphabet)))])
}
return token
}
func cryptoRandSecure(max int64) int64 {
nBig, err := rand.Int(rand.Reader, big.NewInt(max))
if err != nil {
log.Println(err)
}
return nBig.Int64()
}
func main() {
fmt.Println(getToken(32))
}
这将输出如下内容:
qZDbuPwNQGrgVmZCU9A7FUWbp8eIfn0Z
EwZVoQ5D5SEfdhiRsDfH6dU6tAovILCZ
cOqzODVP0GwbiNBwtmqLA78rFgV9d3VT
【问题讨论】:
-
你真的需要一个“密码安全的伪随机数”吗? (来自文档godoc.org/crypto/rand)如果你不这样做,你可以使用godoc.org/math/rand
-
我需要它来生成安全令牌。就像我上面展示的那样。我希望它可以包含字母表中的所有字符,包括数字。
-
刚刚看到您的编辑。另一种方法可能是生成一个非常大的随机 int(如 0 和最大 int64 之间)并将其编码为十六进制或 base32。我会把它添加到我的答案中
-
通常,如果有人需要一个加密强的随机数,她不需要 [0,27] 的范围(即 5 位),而是大得多的范围,更像2048 位,不适合 int64。所以返回了一个 big.int。也许您应该生成一个长比特序列并简单地对其进行 base32 编码?
-
“加密安全 PRNG”和“5 位”不能一起使用。至少一个令牌(例如,用于 CSRF 或会话 ID)应该是 256 位。我会重新考虑你的方法。
标签: go