Pergunta

Eu sei que apenas usando rand() é previsível, se você souber o que está fazendo e tiver acesso ao servidor.

Eu tenho um projeto que é altamente depende da escolha de um número aleatório que seja tão imprevisível quanto possível.Então, estou procurando sugestões, sejam outras funções internas ou funções do usuário, que possam gerar um melhorar número aleatório.

Usei isso para fazer um pequeno teste:

$i = 0;

while($i < 10000){
    $rand = rand(0, 100);

    if(!isset($array[$rand])){
        $array[$rand] = 1;
    } else {
        $array[$rand]++;
    }

    sort($array);
    $i++;
}

Descobri que os resultados estão distribuídos uniformemente e há um padrão estranho no número de vezes que cada número é gerado.

Foi útil?

Solução

Adicionar, multiplicar ou truncar uma fonte aleatória ruim resultará em um resultado aleatório ruim.Ver Introdução à aleatoriedade e aos números aleatórios para uma explicação.

Você está certo sobre a função PHP Rand().Veja a segunda figura em Análise Estatística para uma ilustração impressionante.(A primeira figura é impressionante, mas foi desenhada por Scott Adams, não plotada com Rand()).

Uma solução é usar um gerador aleatório verdadeiro, como aleatório.org.Outra, se você estiver no Linux/BSD/etc.é usar /dev/aleatório.Se a aleatoriedade for de missão crítica, você terá que usar um gerador aleatório de hardware.

Outras dicas

aleatório.org tem uma API que você pode acessar via HTTP.

Random.org é um verdadeiro serviço de números aleatórios que gera aleatoriedade através do ruído atmosférico.

Eu ficaria cauteloso com a impressão de aleatoriedade:houve muitos experimentos em que as pessoas escolheriam a distribuição menos aleatória.Parece que a mente não é muito boa em produzir ou estimar a aleatoriedade.

Existem bons artigos sobre aleatoriedade em Fourmilab, incluindo outro gerador aleatório verdadeiro.Talvez você possa obter dados aleatórios de ambos os sites, então, se um estiver inativo, você ainda terá o outro.

Fourmilab também fornece um programa de teste para verificar a aleatoriedade.Você poderia usá-lo para verificar seus vários programas myRand().

Quanto ao seu último programa, se você gera 10.000 valores, por que não escolhe o valor final entre os 10 mil?Você se restringe a um subconjunto.Além disso, não funcionará se $min e $max forem maiores que 10.000.

De qualquer forma, a aleatoriedade necessária depende da sua aplicação.rand() será adequado para um jogo online, mas não adequado para criptografia (qualquer coisa que não seja completamente testada com programas estatísticos não será adequada para criptografia de qualquer maneira).Você é o juíz!

Variação em @KG, usando os milissegundos desde EPOCH como semente para rand?

Outra maneira de obter números aleatórios, semelhante em conceito ao UUID

PHP versão 5.3 e superior

openssl_random_pseudo_bytes(...)

Ou você pode tentar o seguinte biblioteca usando RFC4122

Um novo PHP7 existe uma função que faz exatamente o que você precisava:isso gera inteiros pseudo-aleatórios criptograficamente seguros.

int random_int ( int $min , int $max )

Gera números inteiros aleatórios criptográficos que são adequados para uso onde resultados imparciais são críticos (ou seja,embaralhar um baralho de pôquer).

Para uma explicação mais detalhada sobre PRNG e CSPRNG (e suas diferenças), bem como por que sua abordagem original é na verdade uma má ideia, leia meu outra resposta altamente semelhante.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top