cpp

Генерация псевдослучайных чисел

Для генерации псевдослучайных чисел можно использовать функции из пакета math/rand. Инструкция импорта:

import "math/rand"

Прежде чем генерировать псевдослучайные числа нужно настроить генератор случайных чисел на новую последовательность. Для этого используется функция Seed(). Формат функции:

rand.Seed(seed int64)

В качестве параметра обычно используется значение, возвращаемое методом UnixNano(). Метод возвращает количество наносекунд, прошедшее с 1 января 1970 г. Пример:

// import "time"
rand.Seed(time.Now().UnixNano())

Если функция Seed() вызвана с одним и тем же параметром, то будет генерироваться одна и та же последовательность псевдослучайных чисел:

rand.Seed(100)
fmt.Println(rand.Int()) // 7530908113823513298
rand.Seed(100)
fmt.Println(rand.Int()) // 7530908113823513298

Пакет math/rand содержит следующие основные функции:

  • Int() — возвращает псевдослучайное целое число от 0 до MaxInt. Формат функции:
rand.Int() int

Пример:

rand.Seed(time.Now().UnixNano())
fmt.Println(rand.Int()) // 7294194540392239655
fmt.Println(rand.Int()) // 5821671445072500835
  • Intn() — возвращает псевдослучайное целое число от 0 до n - 1. Формат функции:
rand.Intn(n int) int

Пример:

rand.Seed(time.Now().UnixNano())
fmt.Println(rand.Intn(10)) // 4
fmt.Println(rand.Intn(10)) // 9
  • Int31() — возвращает псевдослучайное целое число от 0 до MaxInt32. Формат функции:
rand.Int31() int32

Пример:

rand.Seed(time.Now().UnixNano())
fmt.Println(rand.Int31()) // 613577280
fmt.Println(rand.Int31()) // 778211293
  • Int31n() — возвращает псевдослучайное целое число от 0 до n - 1. Формат функции:
rand.Int31n(n int32) int32

Пример:

rand.Seed(time.Now().UnixNano())
fmt.Println(rand.Int31n(10)) // 8
fmt.Println(rand.Int31n(10)) // 1
  • Int63() — возвращает псевдослучайное целое число от 0 до MaxInt64. Формат функции:
rand.Int63() int64

Пример:

rand.Seed(time.Now().UnixNano())
fmt.Println(rand.Int63()) // 2661235360325218757
fmt.Println(rand.Int63()) // 1512300564709233934
  • Int63n() — возвращает псевдослучайное целое число от 0 до n - 1. Формат функции:
rand.Int63n(n int64) int64

Пример:

rand.Seed(time.Now().UnixNano())
fmt.Println(rand.Int63n(10)) // 1
fmt.Println(rand.Int63n(10)) // 4
  • Uint32() — возвращает псевдослучайное целое число типа uint32. Формат функции:
rand.Uint32() uint32

Пример:

rand.Seed(time.Now().UnixNano())
fmt.Println(rand.Uint32()) // 1102188218
fmt.Println(rand.Uint32()) // 2598422068
  • Uint64() — возвращает псевдослучайное целое число типа uint64. Формат функции:
rand.Uint64() uint64

Пример:

rand.Seed(time.Now().UnixNano())
fmt.Println(rand.Uint64()) // 87634494816758201
fmt.Println(rand.Uint64()) // 15899332517991371329
  • Float32() — возвращает псевдослучайное вещественное число от 0 до 1 типа float32. Формат функции:
rand.Float32() float32

Пример:

rand.Seed(time.Now().UnixNano())
fmt.Println(rand.Float32()) // 0.2359201
fmt.Println(rand.Float32()) // 0.38376328
  • Float64() — возвращает псевдослучайное вещественное число от 0 до 1 типа float64. Формат функции:
rand.Float64() float64

Пример:

rand.Seed(time.Now().UnixNano())
fmt.Println(rand.Float64()) // 0.5428960485965229
fmt.Println(rand.Float64()) // 0.6503387173911008

Если нужно, чтобы число генерировалось в диапазоне от min до max включительно, то можно воспользоваться следующим кодом:

rand.Seed(time.Now().UnixNano())
var min, max float64 = 5, 10
var n = math.Floor(rand.Float64() * (max - min + 1) + min)
fmt.Println(n) // Например, 7
  • ExpFloat64() — возвращает псевдослучайное вещественное число от 0 до MaxFloat64. Формат функции:
rand.ExpFloat64() float64

Пример:

rand.Seed(time.Now().UnixNano())
fmt.Println(rand.ExpFloat64()) // 1.9667395320828678
fmt.Println(rand.ExpFloat64()) // 3.7494726087720576
  • NormFloat64() — возвращает псевдослучайное вещественное число от -MaxFloat64 до MaxFloat64. Формат функции:
rand.NormFloat64() float64

Пример:

rand.Seed(time.Now().UnixNano())
fmt.Println(rand.NormFloat64()) // 0.23168128786600417
fmt.Println(rand.NormFloat64()) // -0.02768399272604305
  • Perm() — возвращает слайс из n элементов со псевдослучайными числами от 0 до n - 1. Формат функции:
rand.Perm(n int) []int

Пример:

rand.Seed(time.Now().UnixNano())
fmt.Println(rand.Perm(10)) // [2 0 4 1 8 9 7 3 5 6]
fmt.Println(rand.Perm(10)) // [3 0 1 8 9 2 4 5 6 7]
  • Read() — заполняет слайс псевдослучайными числами. Формат функции:
rand.Read(p []byte) (n int, err error)

Пример:

rand.Seed(time.Now().UnixNano())
bytes := make([]byte, 10)
fmt.Println(rand.Read(bytes)) // 10 <nil>
fmt.Println(bytes) // [96 25 196 25 1 140 248 27 146 237]
  • Shuffle() — позволяет перемешать последовательность случайным образом. Формат функции:
rand.Shuffle(n int, swap func(i int, j int))

Пример:

rand.Seed(time.Now().UnixNano())
arr := []int{1, 2, 3, 4, 5}
rand.Shuffle(len(arr), func(i int, j int) {
   arr[i], arr[j] = arr[j], arr[i]
})
fmt.Println(arr) // [2 3 4 1 5]

В качестве примера создадим генератор паролей произвольной длины (листинг 4.1).

Листинг 4.1. Генератор паролей

package main

import (
   "fmt"
   "math/rand"
   "time"
)

func main() {
   rand.Seed(time.Now().UnixNano())
   fmt.Println(PasswordGenerator(8))  // PHLK5xHj
   fmt.Println(PasswordGenerator(8))  // lGAjRw3c
   fmt.Println(PasswordGenerator(10)) // aSbVlbdXvv
}
func PasswordGenerator(n int) string {
   arr := []rune{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
   'k', 'l', 'm', 'o', 'n', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
   'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
   'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
   'X', 'Y', 'Z', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0'}
   passw := make([]rune, n)
   for i := range passw {
      passw[i] = arr[rand.Intn(len(arr))]
   }
   return string(passw)
}

Вместо использования функций из пакета math/rand можно создать объект структуры Rand и вызывать методы этой структуры. Получить указатель на объект позволяет функция New():

rand.New(src rand.Source) *rand.Rand

Пример:

gen := rand.New(rand.NewSource(time.Now().UnixNano()))

Методы структуры Rand:

(*rand.Rand).Seed(seed int64)
(*rand.Rand).Int() int
(*rand.Rand).Intn(n int) int
(*rand.Rand).Int31() int32
(*rand.Rand).Int31n(n int32) int32
(*rand.Rand).Int63() int64
(*rand.Rand).Int63n(n int64) int64
(*rand.Rand).Uint32() uint32
(*rand.Rand).Uint64() uint64
(*rand.Rand).Float32() float32
(*rand.Rand).Float64() float64
(*rand.Rand).ExpFloat64() float64
(*rand.Rand).NormFloat64() float64
(*rand.Rand).Perm(n int) []int
(*rand.Rand).Read(p []byte) (n int, err error)
(*rand.Rand).Shuffle(n int, swap func(i int, j int))

Все методы аналогичны одноименным функциям, рассмотренным нами ранее. Пример получения псевдослучайного числа от 0 до 9:

gen := rand.New(rand.NewSource(time.Now().UnixNano()))
fmt.Println(gen.Intn(10)) // 1
На заметку

Учебник Go (Golang)
Учебник Go (Golang) в формате PDF

Помощь сайту

ЮMoney (Yandex-деньги): 410011140483022

ПАО Сбербанк:
Счет: 40817810855006152256
Реквизиты банка:
Наименование: СЕВЕРО-ЗАПАДНЫЙ БАНК ПАО СБЕРБАНК
Корреспондентский счет: 30101810500000000653
БИК: 044030653
КПП: 784243001
ОКПО: 09171401
ОКОНХ: 96130
Скриншот реквизитов

cpp