C# - Gerando números aleatórios


Gerar números aleatórios (ou randômicos) na linguagem C# é simples : basta usar a classe Random.

Na definição da MSDN esta classe representa um gerador de números pseudo-aleatório, um dispositivo que produz uma seqüência de números que atendem a certos requisitos estatísticos para aleatoriedade.

Esses números pseudo-aleatório são escolhidos com probabilidade igual a partir de um conjunto finito de números. Os números escolhidos não são completamente aleatórios, porque um algoritmo matemático definido é usado para selecioná-los, mas são suficientemente aleatórios para fins práticos.

Geração de números aleatórios começa a partir de um valor de semente (seed) . Se a mesma semente for usada repetidamente, a mesma série de números será gerada.

Uma maneira de produzir diferentes seqüências é fazer com que o valor de semente seja dependente do tempo, produzindo assim uma série diferente com cada nova instância de Random. Por padrão, o construtor sem parâmetros da classe Random usa o relógio do sistema para gerar o valor de semente.

Obs: Como o relógio tem uma resolução finita, usando o construtor sem parâmetros para criar diferentes objetos Random em sucessão seguida cria geradores de números aleatórios que produzem idênticas seqüências de números aleatórios.

O exemplo mais simples que podemos mostra na linguagem C# para gerar números aleatórios é dado abaixo:

Random randNum = new Random();
randNum.Next();
A classe Random esta no namespace System

Criamos o objeto randNum da classe Random e usamos o método Next() que retorna um número inteiro aleatório.

Vamos mostrar isso na prática criando um novo projeto no Visual C# 2010 Express Edition chamado NumerosAleatórios;

No formulário padrão form1.cs vamos incluir um controle ListBox (listaResultado) e um controle Button (btnGeraNumeros);

Figura 1.0 - O projeto Windows Forms Figura 2.0 - Os números aleatórios gerados

No evento Click do botão de comando vamos incluir o código:

private void btnGeraNumeros_Click(object sender, EventArgs e)
{
   Random randNum = new Random();

   for (int i = 0; i <= 10; i++)
       listaResultado.Items.Add(randNum.Next());
}
o método Next() que retorna um número aleatório não negativo.

Executando o projeto obtemos os 11 números aleatórios usando o método Next() que retorna um número aleatório não negativo.

Você pode obter mais controle sobre os números gerados como gerar números entre uma intervalo de valores.

Vamos supor que você deseja gerar números menor que 100. Para isso basta alterar o código incluindo o número 100 como parâmetro do método Next();

private void btnGeraNumeros_Click(object sender, EventArgs e)
{
   Random randNum = new Random();

   for (int i = 0; i <= 10; i++)
       listaResultado.Items.Add(randNum.Next(100));
}

Isso irá gerar números não maiores que 100 (inclusive).Abaixo temos o resultado da execução :

O método Next(Int32) - Retorna um número aleatório não-negativo menor do que o máximo especificado.

E se você precisar gerar números entre um intervalo de números ?

Sem problemas.

Use o método Next(int1, int2).

Este método retorna um número aleatório dentro de um intervalo especificado.

Inclua outro controle Button(btnGerarNumerosNext2) no formulário e no seu evento Click digite o código a seguir:

private void btnGerarNumerosNext2_Click(object sender, EventArgs e)
 {
            Random randNum = new Random();
            for (int i = 0; i < 10; i++)
                listaResultado.Items.Add(randNum.Next(100,200));
}

O código acima irá gerar números aleatórios entre 100 e 200.

Executando o código acima teremos:

O método Next(minimo,maximo) gera número aleatórios no intervalo definido.

Como ja foi dito, no construtor padrão do objeto Random(), será gerada uma semente de forma automática, baseada na hora atual do sistema, mas você pode definir uma semente para geração dos números indicando no construtor da classe Random;

Inclua um novo controle Button no formulário com o nome btnGerarNumerosComSeed e inclua no evento Click deste botão o código  abaixo:

private void btnGerarNumerosComSeed_Click(object sender, EventArgs e)
{
   Random randNum = new Random(2012);

   for (int i = 0; i <= 10; i++)
       listaResultado.Items.Add(randNum.Next());
}

No código acima definimos o valor 2012 como semente para geração dos números aleatórios e a cada execução do método Next() teremos a geração de um número diferente baseado nesta semente:

O construtor da classe Random(inteiro) permite definir uma semente para geração de números aleatórios

Esteja atento ao fato de que se você gerar a mesma semente novamente a mesma sequência de números será gerada. Teste isso interrompendo o programa e executando-o novamente, você verá que a mesma sequência será gerada.

Se você precisar gerar números aleatórios entre 0 e 1 com precisão basta usar o método NextDouble();

Inclua um novo botão (btnGerarNumerosDouble) no formulário e no seu evento Click digite o código abaixo:

 private void btnGerarNumerosDouble_Click(object sender, EventArgs e)
 {
            Random randNum = new Random();
            for (int i = 0; i < 10; i++)
                listaResultado.Items.Add(randNum.NextDouble());
  }

Abaixo temos o resultado obtido:

O método NextDouble() gera um número double entre 0 e 1

Para concluir temos o método NextBytes() que preenche os elementos de um conjunto especificado de bytes com números aleatórios. Dessa forma cada elemento do array será um byte com valor entre 0 e 255.

Vamos incluir um novo Button (btnGerarNumerosNextBytes) no formulário e no evento Click informar o código abaixo:

  private void btnGerarNumeroNextByte_Click(object sender, EventArgs e)
        {
            byte[] randBytes = new byte[100];
            Random randNum = new Random();
            randNum.NextBytes(randBytes);

            for (int i = 0; i < 10; i++)
                listaResultado.Items.Add(randBytes[i]);
        }

No código acima definimos um array de bytes para 100 elementos; a seguir criamos uma instância de Random() e depois usando o método NextBytes preenchemos o array com números aleatórios;

Abaixo temos o resultado obtido:

Dessa forma apresentamos a classe Random() e seus métodos para gerar números aleatórios.

Para encerrar vamos mostrar um exemplo prático para gera senhas usando a classe Random(). (esta rotina foi obtida do site: http://csharpbrasil.com.br/csharp/dica-gerando-numeros-randomicos-com-c-sharp/ )

Vamos definir a rotina abaixo no formulário acima:

 public string GerarSenhas()
        {
            int Tamanho = 10; // Numero de digitos da senha
            string senha = string.Empty;
            for (int i = 0; i < Tamanho; i++)
            {
                Random random = new Random();
                int codigo = Convert.ToInt32(random.Next(48, 122).ToString());

                if ((codigo >= 48
&& codigo <= 57) || (codigo >= 97 && codigo <= 122))
                {
                    string _char = ((char)codigo).ToString();
                    if (!senha.Contains(_char))
                    {
                        senha += _char;
                    }
                    else
                    {
                        i--;
                    }
                }
                else
                {
                    i--;
                }
            }
            return senha;
        }

Inclua um novo botão de comando no formulário (btnGerarSenha) e no evento Click inclua o código abaixo:

 private void btnGerarSenha_Click(object sender, EventArgs e)
 {
            string senha = GerarSenhas();
            listaResultado.Items.Add(" Senha gerada : " + senha.ToUpper());
 }

O resultado é o seguinte:

Pegue o projeto completo aqui: NumerosAleatórios.zip

Protestaram, pois, os judeus, perguntando-lhe: Que sinal de autoridade nos mostras, uma vez que fazes isto?
Respondeu-lhes Jesus: Derribai este santuário, e em três dias o levantarei.
Disseram, pois, os judeus: Em quarenta e seis anos foi edificado este santuário, e tu o levantarás em três dias?
Mas ele falava do santuário do seu corpo.

João 2:18-21

Referências:


José Carlos Macoratti