O pacote rand64 fornece geradores de números pseudo-aleatórios que produzem números não assinados de 64 bits no intervalo [0, 2 64 ).
Implementações para os seguintes geradores de números pseudo-aleatórios são fornecidas em seus próprios pacotes:
Esses geradores implementam rand.Source64, para que possam ser usados como fonte para rand.Rand (a partir do Go 1.8).
Observe que alguns algoritmos fazem uso do pacote bits do Go 1.9.
A criação de um PRNG é assim:
// 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)
Esta é uma versão de incremento fixo do gerador SplittableRandom do Java 8. Veja também a página sobre Geradores de números pseudoaleatórios de divisão rápida.
Implementação Go baseada em uma implementação de referência C de Sebastiano Vigna.
Período 2 256 -1
De acordo com os autores do algoritmo:
xoshiro256** (XOR/shift/rotate) é nosso gerador sólido e multifuncional (embora não seja um gerador criptograficamente seguro). Possui excelente velocidade (sub-ns), um espaço de estados (256 bits) grande o suficiente para qualquer aplicação paralela e passa em todos os testes que conhecemos.
Se, no entanto, for necessário gerar apenas números de ponto flutuante de 64 bits (extraindo os 53 bits superiores), o xoshiro256+ é um gerador ligeiramente (≈15%) mais rápido com propriedades estatísticas análogas. Para uso geral, deve-se considerar que seus bits mais baixos têm baixa complexidade linear e falharão nos testes de linearidade; no entanto, a baixa complexidade linear dificilmente pode ter qualquer impacto na prática e certamente não terá nenhum impacto se você gerar números de ponto flutuante usando os bits superiores (calculamos uma estimativa precisa da complexidade linear dos bits mais baixos).
Período 2 128 -1
De acordo com os autores do algoritmo:
xoroshiro128** (XOR/girar/shift/girar) e xoroshiro128+ têm a mesma velocidade que xoshiro256 e usam metade do espaço; os mesmos comentários se aplicam. Eles são adequados apenas para aplicações paralelas de baixa escala; além disso, xoroshiro128+ exibe uma leve dependência nos pesos de Hamming que gera uma falha após 5 TB de saída em nosso teste. Acreditamos que este ligeiro viés não pode afetar nenhuma aplicação.
Implementação Go baseada em uma implementação de referência C de David Blackman e Sebastiano Vigna.
Para mais informações, visite os geradores xoshiro/xoroshiro e a página do tiroteio PRNG.
Período 2 128
Este é um gerador congruente permutado conforme definido em
PCG: uma família de algoritmos simples, rápidos, eficientes em termos de espaço e estatisticamente bons para geração de números aleatórios
Melissa E. O'Neill, Harvey Mudd College
https://www.cs.hmc.edu/tr/hmc-cs-2014-0905.pdf
Embora PCG
se refira a toda uma família de algoritmos (veja também http://pcg-random.org), o único algoritmo fornecido é PCG XSL RR 128/64 LCG.
Implementação Go baseada na implementação de referência C por Melissa O'Neill e os contribuidores do Projeto PCG.
Período 2 19937 -1
Esta é uma implementação Go pura baseada na implementação C mt19937-64.c de Makoto Matsumoto e Takuji Nishimura.
Mais informações sobre o algoritmo Mersenne Twister e outras implementações estão disponíveis em http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
Observe que este algoritmo se destina apenas a aplicações que necessitam de interoperabilidade com outras aplicações que utilizam este mesmo algoritmo. Como é conhecido por falhar em testes estatísticos triviais e ser o mais lento no AMD64, seu uso para qualquer outra finalidade não é recomendado.
Não é um PRNG real.
O pacote IoRand é um wrapper simples para leitura de fluxos de bytes via io.Reader. Ele pode ser usado como um wrapper em torno de crypto/rand para construir um rand.Source64 para o pacote 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 ()
}
}
Esses benchmarks foram concluídos com o 1.12.5.
Algoritmo | AMD FX-6300 | Core i5 6200U | ARM Cortex-A7 @900MHz |
---|---|---|---|
xoshiro256** | 5,53 ns/op | 106,0 ns/op | |
xoshiro256+ | 5,48 ns/op | 86,1 ns/op | |
xoroshiro128** | 5,16 ns/op | 79,2 ns/op | |
xoroshiro128+ | 5,15 ns/op | 62,7 ns/op | |
PCG XSL RR 128/64 LCG | 5,29 ns/op | 254,0 ns/op | |
splitmix64 | 4h30 ns/op | 77,5 ns/op | |
Mersenne Twister 19937 | 8,82 ns/op | 136,0 ns/op | |
Vá matemática/rand | 7,01 ns/op | 68,4 ns/op |
Observe que os benchmarks mostram um desempenho mais lento em comparação com versões anteriores. Isso se deve ao fato de termos chamado Rng.Uint64 diretamente, em vez de passar pela interface rand.Rand64. Para fazer uma comparação justa com o rng da biblioteca padrão Go, todos os benchmarks agora passam por uma interface rand.Source64.
Fique longe do splitmix64 e do venerável Mersenne-Twister 19937.
Muito pouco se sabe sobre a matemática/rand do Go (veja aqui, aqui) e há uma proposta para substituí-lo por um gerador PCG.
Os PCG fornecidos, xoshiro256** e xoroshiro128** têm a reputação de passar em todos os testes conhecidos; segundo seus respectivos autores. Cuidado com o baixo desempenho deste algoritmo PCG específico em plataformas de 32 bits (afeta ARM e x86).
rand64 suporta módulos go. As versões anteriores 1.xe 2.x foram movidas para suas respectivas ramificações. Como as tags semver sem go.mod pareciam perturbar os módulos go, as tags para essas versões foram redefinidas.
Este pacote é lançado sob os termos da licença ISC (veja o arquivo LICENSE na raiz do repositório). Além disso, o uso dos seguintes algoritmos é regido por licenças adicionais: