Создание случайных чисел в Go
Я пытаюсь генерировать случайные числа (целые числа) в Go, но безрезультатно. Я нашел пакет rand
в crypto/rand
, который, кажется, является тем, что я хочу, но я не могу сказать из документации, как используй это. Это то, что я сейчас пытаюсь сделать:
b := []byte{}
something, err := rand.Read(b)
fmt.Printf("something = %v\n", something)
fmt.Printf("err = %v\n", err)
Но, к сожалению, это всегда выводит:
something = 0
err = <nil>
Есть ли способ исправить это, чтобы он фактически генерировал случайные числа? Альтернативно, существует ли способ установить верхнюю границу на случайные числа, которые это генерирует?
Ответы
Ответ 1
crypto/rand
предоставляет только двоичный поток случайных данных, но вы можете читать целые числа из него с помощью encoding/binary
:
package main
import "encoding/binary"
import "crypto/rand"
func main() {
var n int32
binary.Read(rand.Reader, binary.LittleEndian, &n)
println(n)
}
Ответ 2
В зависимости от вашего варианта использования другой вариант - это пакет math/rand
. Не делайте этого, если вы генерируете числа, которые должны быть совершенно непредсказуемыми. Это может быть полезно, если вам нужно получить результаты, которые воспроизводимы, однако - просто передайте одно и то же семя, которое вы передали в первый раз.
Здесь классическая программа "Запускать генератор с текущим временем и сгенерировать число":
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
rand.Seed(time.Now().Unix())
fmt.Println(rand.Int())
}
Ответ 3
Начиная с 1 апреля 2012 года, после выпуска стабильной версии lang, вы можете сделать следующее:
package main
import "fmt"
import "time"
import "math/rand"
func main() {
rand.Seed(time.Now().UnixNano()) // takes the current time in nanoseconds as the seed
fmt.Println(rand.Intn(100)) // this gives you an int up to but not including 100
}