Pergunta

Como posso gerar valores aleatórios Int64 e UInt64 usando a classe Random em C #?

Foi útil?

Solução

Isso deve fazer o truque. (É um método de extensão para que você possa chamá-lo apenas como você chamar os Next ou NextDouble métodos normais em um objeto Random).

public static Int64 NextInt64(this Random rnd)
{
    var buffer = new byte[sizeof(Int64)];
    rnd.NextBytes(buffer);
    return BitConverter.ToInt64(buffer, 0);
}

Basta substituir Int64 com UInt64 em todos os lugares, se você quiser números inteiros sem sinal, em vez e tudo deve funcionar bem.

Nota: Uma vez que nenhum contexto foi fornecido sobre a segurança ou a aleatoriedade desejada dos números gerados (na verdade, o OP mencionou especificamente a classe Random), meu exemplo simplesmente lida com a classe Random, que é a solução preferida quando aleatoriedade (frequentemente quantificada como informações entropia ) não é um problema. Por uma questão de interesse, consulte as outras respostas que RNGCryptoServiceProvider menção (RNG fornecido no namespace System.Security), que pode ser usado de forma quase idêntica.

Outras dicas

Use Random.NextBytes() e BitConverter.ToInt64 / BitConverter.ToUInt64 .

// Assume rng refers to an instance of System.Random
byte[] bytes = new byte[8];
rng.NextBytes(bytes);
long int64 = BitConverter.ToInt64(bytes, 0);
ulong uint64 = BitConverter.ToUInt64(bytes, 0);

Note que o uso Random.Next() duas vezes, mudando um valor e, em seguida, ORing / acrescentando não funciona. Random.Next() só produz inteiros não negativos, isto é, que gera 31 bits, não 32, de modo que o resultado de duas chamadas apenas produz 62 bits aleatórios em vez dos 64 bits requeridos para cobrir a gama completa de Int64 / UInt64. (A resposta de Guffa mostra como fazê-lo com três chamadas para Random.Next() embora.)

Aqui está, este usa o serviços crytpo (não a classe Random) , que é (teoricamente) uma melhor RNG então a classe Random. Você poderia facilmente fazer isso uma extensão da Random ou fazer a sua própria classe Random onde o RNGCryptoServiceProvider é um objeto de nível de classe.

using System.Security.Cryptography;
public static Int64 NextInt64()
{
   var bytes = new byte[sizeof(Int64)];    
   RNGCryptoServiceProvider Gen = new RNGCryptoServiceProvider();
   Gen.GetBytes(bytes);    
   return BitConverter.ToInt64(bytes , 0);        
}

Você pode usar o deslocamento pouco para montar um 64 bit número aleatório de 31 bits números aleatórios, mas você tem que usar três 31 números de bits para obter bits suficientes:

long r = rnd.Next();
r <<= 31;
r |= rnd.Next();
r <<= 31;
r |= rnd.Next();

Eu sempre uso isso para obter a minha semente aleatória (verificação de erro removido por brevidade):

m_randomURL = "https://www.random.org/cgi-bin/randnum?num=1&min=1&max=1000000000";
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(m_randomURL);
StreamReader stIn = new StreamReader(req.GetResponse().GetResponseStream());
Random rand = new Random(Convert.ToInt32(stIn.ReadToEnd()));

random.org usa ruído atmosférico para gerar a aleatoriedade e é aparentemente usado para loterias e tal.

Você não diz como você está indo para usar esses números aleatórios ... ter em mente que os valores devolvidos pela Aleatório não são "criptograficamente seguro" e não devem ser utilizados para coisas que envolvem (grandes) segredos ou (lotes de) dinheiro.

Você pode criar uma matriz byte , preenchê-lo com aleatório de dados e, em seguida, convertê-lo para long (Int64) e ulong (UInt64).

byte[] buffer = new byte[sizeof(Int64)];
Random random = new Random();

random.NextBytes(buffer);
long signed = BitConverter.ToInt64(buffer, 0);

random.NextBytes(buffer);
long unsigned = BitConverter.ToUInt64(buffer, 0);

Outra resposta com RNGCryptoServiceProvider vez de Random. Aqui você pode ver como remover o MSB de modo que o resultado é sempre positivo.

public static Int64 NextInt64()
{
    var buffer = new byte[8];
    new RNGCryptoServiceProvider().GetBytes(buffer);
    return BitConverter.ToInt64(buffer, 0) & 0x7FFFFFFFFFFFFFFF;
}
Random r=new Random();
int j=r.next(1,23);
Console.WriteLine(j);
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top