在 Go 中生成固定长度随机数最快、最简单的方法是什么?
假设要生成 8 位长数字,
rand.Intn(100000000)
的问题是结果可能远小于 8 位,并且用前导零填充对我来说看起来不是一个好的答案。
也就是说,我更关心随机性的质量,因为它的长度。所以我在想,对于这个具体问题,以下是最快、最简单的方法吗?
99999999 - rand.Int63n(90000000)
即,我猜
Int63n
可能比Intn
更适合我的情况。这是真的,还是只是一厢情愿?关于全8位的随机性,两者会相同,还是真的有一个比另一个更好?
最后,还有比上面更好的方法吗?
更新:
请不要提供
low + rand(hi-low)
作为答案,众所周知。它相当于我现在正在做的事情,并且它没有回答我真正的问题,“关于完整8位数字的随机性,两者会相同,还是真的有一个比另一个更好?”
如果没有人能回答这个问题,我会在两者之间绘制一个二维散点图,然后自己找出答案......
谢谢
这是一个通用函数,用于生成一定范围内的数字
func rangeIn(low, hi int) int {
return low + rand.Intn(hi-low)
}
在游乐场
看到它在您的具体情况下,尝试生成 8 位数字,范围将是
(10000000, 99999999)
这取决于您要使用的值范围。
如果允许值范围[0-99999999]并填充字符的零ip数< 8, then use fmt like
fmt.Sprintf("%08d",rand.Intn(100000000))
。 如果您不需要填充,其值在 [10000000, 99999999] 范围内,则给它一个基数,如
ranNumber := 10000000
+ rand.Intn(90000000)`crypto/rand 包用于生成数字。
func generateRandomNumber(numberOfDigits int) (int, error) {
maxLimit := int64(int(math.Pow10(numberOfDigits)) - 1)
lowLimit := int(math.Pow10(numberOfDigits - 1))
randomNumber, err := rand.Int(rand.Reader, big.NewInt(maxLimit))
if err != nil {
return 0, err
}
randomNumberInt := int(randomNumber.Int64())
// Handling integers between 0, 10^(n-1) .. for n=4, handling cases between (0, 999)
if randomNumberInt <= lowLimit {
randomNumberInt += lowLimit
}
// Never likely to occur, kust for safe side.
if randomNumberInt > int(maxLimit) {
randomNumberInt = int(maxLimit)
}
return randomNumberInt, nil
}
我最近需要做这样的事情,但是具有一定的字节长度(而不是位数)并且数字大于最大 int64 (因此使用 math/big.Int)。这是我的一般解决方案:
参见 Playground(添加了代码注释)
func generateRandomBigInt(numBytes int) (*big.Int, error) {
value := make([]byte, numBytes)
_, err := rand.Reader.Read(value)
if err != nil {
return nil, err
}
for true {
if value[0] != 0 {
break
}
firstByte := value[:1]
_, err := rand.Reader.Read(firstByte)
if err != nil {
return nil, err
}
}
return (&big.Int{}).SetBytes(value), nil
}
随机数的简单版本是:
func randNumber(n int) int {
minLimit := int(math.Pow10(n))
maxLimit := int(math.Pow10(n - 1))
randInt := int(rand.Float64() * float64(minLimit))
if randInt < maxLimit {
randInt += maxLimit
}
return randInt
}
func main() {
fmt.Println(randNumber(6))
}
这可用于验证码或类似用途
返回随机数,而不是唯一数。如果您需要唯一编号,请使用 UUID 包。