Поиск по сайту:

Генерация случайных чисел с помощью Go


Узнайте, как добавить немного непредсказуемости в свои игры или симуляторы.

Генерация случайных чисел важна для многих задач. К ним относятся разработка игр, криптография и анализ данных. Случайные значения позволяют получить различные результаты с элементом изменчивости и непредсказуемости.

Go предоставляет два пакета для генерации случайных значений в стандартной библиотеке: math/rand и crypto/rand. Пакет math/rand предназначен в основном для математических операций. Пакет crypto/rand обрабатывает криптографически безопасные операции.

Пакеты «Рэнд»

Пакет math/rand предоставляет гибкий метод генерации случайных чисел. Он реализует различные генерации псевдослучайных чисел. Пакет может генерировать случайное число с различными распределениями и использовать начальные числа для управления случайной последовательностью. Он также может генерировать случайные числа одновременно или параллельно.

Пакет crypto/rand реализует криптографически безопасный генератор случайных чисел. Он включает в себя функцию генерации случайных простых чисел с высокой вероятностью.

Поскольку эти пакеты имеют одно и то же имя, вам нужно будет использовать псевдонимы, если вы хотите использовать оба в одной программе, например:

import (
    crand "crypto/rand"
    mrand "math/rand"
)

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

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

import (
    "fmt"
    "math/rand"
    "time"
)
func main() {
    rand.Seed(time.Now().UnixNano())
    // Intn generates a random integer between 0 and 100 
    // (not including 100)
    randomInt := rand.Intn(100) 
    fmt.Println(randomInt)
}

Этот код передает текущее время функции Seed. Он инициализирует генератор случайных чисел по умолчанию для псевдослучайности.

Функция Intn пакета rand генерирует случайное число в указанном диапазоне, в данном случае от 0 до 100.

Генерация случайных чисел с плавающей запятой

Вы можете генерировать случайные числа с плавающей запятой с помощью функций Float32 и Float64. Они возвращают 32-битные и 64-битные числа с плавающей запятой соответственно.

Вот как вы можете генерировать случайные 64-битные числа с плавающей запятой в Go.

import (
    "fmt"
    "math/rand"
    "time"
)
func main() {
    rand.Seed(time.Now().UnixNano())
    // generate a random float64 between 0.0 and 1.0
    randomFloat := rand.Float64()
    fmt.Println(randomFloat)
}

Процесс генерации 32-битных чисел с плавающей запятой аналогичен генерации случайных 64-битных чисел с плавающей запятой.

Генерация криптографически безопасных случайных чисел в Go

Вы можете использовать функцию Int пакета crypto/rand для генерации криптографически безопасного случайного числа. Функция Int принимает экземпляр устройства чтения и максимальное число для ограничения.

import (
    "crypto/rand"
    "fmt"
    "math/big"
)
func main() {
    // Create a big.Int with the maximum value for the desired range
    max := big.NewInt(100000000)
    
    // Generate a random big.Int
    // The first argument is a reader that returns random numbers
    // The second argument is the maximum value (not inclusive)
    randInt, err := rand.Int(rand.Reader, max)
    if err != nil {
        fmt.Println("Error generating random number:", err)
        return
    }
    
    fmt.Println("Random number:", randInt)
}

Переменная max определяет максимальное значение случайного числа с помощью функции NewInt пакета math/big. Функция Int возвращает случайное целое число и ошибку для обработки.

Генерация криптографически безопасных случайных значений

Пакет crypto/rand не предоставляет встроенных функций для генерации криптографически безопасных случайных строк. Тем не менее, вы можете обойти эту проблему, используя функцию Чтение.

import (
    "crypto/rand"
    "fmt"
)
func cryptoRandom(stringChars string, valueLength int32) string {
    bytesSlice := make([]byte, valueLength)
    _, err := rand.Read(bytesSlice)
    if err != nil {
        return "There was an error reading from the byte slice"
    }
    for pos, value := range bytesSlice {
        randomize := value % byte(len(stringChars))
        bytesSlice[pos] = stringChars[randomize]
    }
    return string(bytesSlice)
}
func main() {
    fmt.Println(cryptoRandom("Pneumonoultram" +
        "icroscopicsilicovolcanoconiosis", 10))
}

Приведенная выше функция cryptoRandom принимает строку для генерации случайной строки. Он также принимает длину — 32-битное целое число — и возвращает строку.

В функции cryptoRandom переменная bytesSlice представляет собой фрагмент строки необходимой длины. Цикл for-range обходит байтовый срез и возвращает и извлекает модуль элементов среза и длину строки в байтах. Он обновляет индекс байтового среза индексом значения по модулю строки.

Наконец, функция cryptoRandom возвращает строковый формат байтового среза.

Вы можете генерировать UUID с помощью Go

Генерация случайных значений пригодится в самых разных случаях. Если вам нужно много случайных уникальных значений, вы можете использовать UUID.

UUID (универсальные уникальные идентификаторы) обеспечивают глобальную уникальность идентификаторов. Вы можете использовать их, чтобы различать ресурсы в разных системах, избегая при этом конфликтов имен.

Существует множество пакетов, которые вы можете использовать для генерации UUID в Go. Вы можете использовать пакет os для вызова команды uuid в вашей операционной системе, воспользоваться пакетом UUID Google или использовать пакет gouuid для генерации UUID.

Статьи по данной тематике: