Pregunta

¿Cómo puedo generar al azar valores Int64 y uint64 utilizando el Random clase en C #?

¿Fue útil?

Solución

Esto debería hacer el truco. (Es un método de extensión de modo que se le puede llamar igual que llamar a los métodos normales Next o NextDouble en un Random objeto).

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

Basta con sustituir Int64 con UInt64 todas partes si quieres enteros sin signo lugar y todo debería funcionar bien.

Nota: Desde que se proporciona ningún contexto en relación con la seguridad o la aleatoriedad deseada de los números generados (de hecho, la OP menciona específicamente la RNGCryptoServiceProvider clase), mi ejemplo, simplemente se ocupa de la System.Security clase, que es la solución preferida cuando la aleatoriedad (a menudo cuantificado como información entropía ) no es un problema. Como un asunto de interés, ver las otras respuestas que mencionan <=> (RNG proporcionado en el espacio de nombres <=>), que puede ser utilizado de manera casi idéntica.

Otros consejos

Random.NextBytes() y 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);

Tenga en cuenta que el uso de Random.Next() dos veces, cambiando un valor y luego la operación lógica OR / añadiendo que no funciona. Int64 sólo produce números enteros no negativos, es decir, que genera 31 bits, no 32, por lo que el resultado de dos llamadas sólo produce 62 bits aleatorios en lugar de los 64 bits requeridos para cubrir la gama completa de UInt64 / <=>. ( de Guffa respuesta muestra cómo hacerlo con tres llamadas a <=> sin embargo.)

Aquí tiene, este utiliza los servicios de crytpo (no la clase Random) , que es (en teoría) una mejor RNG entonces la clase Random. Desde aquí se puede hacer de este una extensión de azar o hacer su propia clase Random donde el RNGCryptoServiceProvider es un objeto de nivel de clase.

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);        
}

Puede usar el desplazamiento de bits para armar un número aleatorio de 64 bits de números aleatorios 31 bits, pero hay que usar tres números de 31 bits para obtener suficientes bits:

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

Siempre utilizo para conseguir mi semilla aleatoria (comprobación de errores removido por razones de brevedad):

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 utiliza ruido atmosférico para generar la aleatoriedad y aparentemente se utiliza para loterías y tal.

No se dice cómo se va a utilizar estos números aleatorios ... tener en cuenta que los valores devueltos por Al azar no son "criptográficamente seguro" y que no se deben utilizar para cosas que involucran (grandes) o secretos (un montón de dinero).

You could create a byte array, fill it with random data and then convert it to long (Int64) and 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);

Another answer with RNGCryptoServiceProvider instead of Random. Here you can see how to remove the MSB so the result is always positive.

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 bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top