Пакет rand64 предоставляет генераторы псевдослучайных чисел, выдающие 64-битные беззнаковые числа в диапазоне [0, 2 64 ).
Реализации для следующих генераторов псевдослучайных чисел предоставляются в отдельных пакетах:
Эти генераторы реализуют rand.Source64, поэтому их можно использовать в качестве источника для rand.Rand (начиная с Go 1.8).
Обратите внимание, что некоторые алгоритмы используют пакет битов из Go 1.9.
Создание PRNG выглядит следующим образом:
// create a source with the xoshiro256**
source := &xoshiro.Rng256SS{}
// use it as a source in rand.New
rng := rand.New(&source)
// Seed it from a single int64 (negative values are accepted)
rng.Seed(int64Seed)
Это версия генератора SplittableRandom в Java 8 с фиксированным приращением. См. также страницу «Быстрые разделяемые генераторы псевдослучайных чисел».
Реализация Go основана на эталонной реализации C, созданной Себастьяно Винья.
Период 2 256 -1
По мнению авторов алгоритма:
xoshiro256** (XOR/shift/rotate) — наш универсальный, надежный генератор (хотя и не криптографически безопасный генератор). Он имеет отличную скорость (субнс), пространство состояний (256 бит), достаточно большое для любого параллельного приложения, и он проходит все известные нам тесты.
Однако если нужно генерировать только 64-битные числа с плавающей запятой (путем извлечения старших 53 битов), xoshiro256+ — немного (≈15%) более быстрый генератор с аналогичными статистическими свойствами. Для общего использования следует учитывать, что его младшие биты имеют низкую линейную сложность и не проходят тесты на линейность; однако низкая линейная сложность вряд ли может иметь какое-либо влияние на практике и, конечно же, не оказывает никакого влияния вообще, если вы генерируете числа с плавающей запятой, используя старшие биты (мы вычислили точную оценку линейной сложности младших битов).
Период 2 128 -1
По мнению авторов алгоритма:
xoroshiro128** (XOR/rotate/shift/rotate) и xoroshiro128+ имеют ту же скорость, что и xoshiro256, и используют половину пространства; применимы те же комментарии. Они подходят только для небольших параллельных приложений; более того, xoroshiro128+ демонстрирует умеренную зависимость весов Хэмминга, что приводит к сбою после 5 ТБ вывода в нашем тесте. Мы считаем, что эта небольшая предвзятость не может повлиять ни на одно приложение.
Реализация Go основана на эталонной реализации C Дэвида Блэкмана и Себастьяно Винья.
Для получения дополнительной информации посетите генераторы xoshiro/xoroshiro и страницу перестрелки PRNG.
Период 2 128
Это перестановочный конгруэнтный генератор, определенный в
PCG: семейство простых быстрых, эффективных и статистически хороших алгоритмов для генерации случайных чисел
Мелисса Э. О'Нил, Колледж Харви Мадда
https://www.cs.hmc.edu/tr/hmc-cs-2014-0905.pdf
Хотя PCG
относится к целому семейству алгоритмов (см. также http://pcg-random.org), единственным представленным алгоритмом является PCG XSL RR 128/64 LCG.
Реализация Go основана на эталонной реализации C Мелиссой О'Нил и участниками проекта PCG.
Период 2 19937 -1
Это чистая реализация Go, основанная на реализации mt19937-64.c C Макото Мацумото и Такудзи Нисимура.
Дополнительную информацию об алгоритме Mersenne Twister и других реализациях можно найти по адресу http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html.
Обратите внимание, что этот алгоритм предназначен только для приложений, которым требуется взаимодействие с другими приложениями, использующими тот же алгоритм. Поскольку известно, что он не проходит тривиальные статистические тесты и является самым медленным на amd64, его использование для каких-либо других целей не рекомендуется.
Не настоящий ГПСЧ.
Пакет IoRand — это простая оболочка для чтения потоков байтов через io.Reader. Его можно использовать в качестве оболочки crypto/rand для создания rand.Source64 для пакета math/rand:
package main
import (
"bufio"
crand "crypto/rand"
"encoding/binary"
"math/rand"
"github.com/db47h/rand64/v3/iorand"
)
// Wrap crypto/rand in an IoRand
func main () {
// first, wrap crypto/rand.Reader in a buffered bufio.Reader
bufferedReader := bufio . NewReader ( crand . Reader )
// Create the new IoRand Source
ior := iorand . New ( bufferedReader , binary . LittleEndian )
// use it as rand.Source64
rng := rand . New ( ior )
// get random numbers...
for i := 0 ; i < 4 ; i ++ {
_ = rng . Uint64 ()
}
}
Эти тесты были выполнены с помощью go 1.12.5.
Алгоритм | AMD FX-6300 | Ядро i5 6200U | ARM Cortex-A7 @ 900 МГц |
---|---|---|---|
xoshiro256** | 5,53 нс/оп | 106,0 нс/оп | |
xoshiro256+ | 5,48 нс/оп | 86,1 нс/оп | |
сороширо128** | 5,16 нс/оп | 79,2 нс/оп | |
сороширо128+ | 5,15 нс/оп | 62,7 нс/оп | |
ПКГ XSL РР 128/64 ЛКГ | 5,29 нс/оп | 254,0 нс/оп | |
сплитмикс64 | 4,30 нс/оп | 77,5 нс/оп | |
Мерсенн Твистер 19937 | 8,82 нс/оп | 136,0 нс/оп | |
Займитесь математикой/рандом | 7,01 нс/оп | 68,4 нс/оп |
Обратите внимание, что тесты показывают более низкую производительность по сравнению с более ранними выпусками. Это связано с тем, что мы вызывали Rng.Uint64 напрямую, а не через интерфейс rand.Rand64. Чтобы провести справедливое сравнение с rng стандартной библиотеки Go, все тесты теперь проходят через интерфейс rand.Source64.
Держитесь подальше от Splitmix64 и почтенного Mersenne-Twister 19937 года.
О math/rand в Go известно очень мало (см. здесь, здесь), и есть предложение заменить его генератором PCG.
Предполагается, что предоставленные PCG, xoshiro256** и xoroshiro128** прошли все известные тесты; по мнению их авторов. Однако обратите внимание на плохую производительность этого конкретного алгоритма PCG на 32-битных платформах (влияет как на ARM, так и на x86).
rand64 поддерживает модули Go. Предыдущие версии 1.x и 2.x были перенесены в соответствующие ветки. Поскольку теги semver без go.mod, похоже, нарушали работу модулей go, теги для этих версий были сброшены.
Данный пакет выпущен на условиях лицензии ISC (см. файл LICENSE в корне репозитория). При этом использование следующих алгоритмов регулируется дополнительными лицензиями: