在 Go 语言中,math/rand
和 crypto/rand
都是用于生成随机数的包,但它们的用途和特性有显著的不同。
1. math/rand
- 类型:伪随机数生成器(PRNG)
- 用途:主要用于生成随机数,适用于模拟、游戏、统计抽样等需要随机性的场合,但不适合安全相关的应用。
- 种子:必须使用种子(seed)来初始化,若使用相同的种子,生成的随机数序列将是相同的。例如:
import (
"math/rand"
"time"
)
func main() {
r := rand.New(rand.NewSource(time.Now().UnixNano())) // 使用当前时间作为种子
number := r.Intn(100) // 生成 0 到 99 之间的随机整数
}
- 特性:容易被预测,因为伪随机数生成器依赖于种子,若种子已知,生成的数列也可预测。
2. crypto/rand
- 类型:加密安全随机数生成器
- 用途:适用于需要高安全性和不可预测性的场景,如加密密钥生成、密码学相关的随机数需求等。
- 特性:生成的随机数不可预测,即使攻击者知道某些输入数据或操作,也无法预测生成的随机数。这使其非常适合安全应用。
import (
"crypto/rand"
"math/big"
)
func main() {
max := big.NewInt(100) // 生成 0 到 99 之间的随机数
n, err := rand.Int(rand.Reader, max)
if err != nil {
// 处理错误
}
// n 是 0 到 99 之间的随机整数
}
对比
特性 |
|
|
---|---|---|
随机数生成类型 | 伪随机数生成器 | 加密安全随机数生成器 |
适用场景 | 模拟、游戏、非安全用途 | 加密、密钥生成、安全用途 |
可预测性 | 可预测(种子已知时) | 不可预测 |
初始化方式 | 必须使用种子 | 不需要种子,自动使用系统熵 |
性能 | 通常更快 | 生成速度较慢(因考虑安全性) |
结论
- 如果你需要生成随机数用于非安全性场景,比如游戏或简单的随机抽样,可以选择
math/rand
。 - 但是如果你需要在安全性方面得到保证,比如生成加密密钥、会话令牌等,则应该使用
crypto/rand
。