2009-03-24 16 views

Respuesta

72

Esto debería hacer el truco. (Es un método de extensión para que pueda llamarlo igual que cuando llama a los métodos normales Next o NextDouble en un objeto Random).

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 con respecto a la seguridad o la aleatoriedad deseada de los números generados (de hecho el OP menciona específicamente la clase Random), mi ejemplo simplemente se ocupa de la clase Random, que es la solución preferida cuando la aleatoriedad (a menudo cuantificada como information entropy) no es un problema. Como una cuestión de interés, vea las otras respuestas que mencionan RNGCryptoServiceProvider (el RNG provisto en el espacio de nombre System.Security), que se puede usar casi de manera idéntica.

+1

+1 para dar al OP lo que pidieron, así como mencionar las limitaciones de usar Random y ofrecer una alternativa si las limitaciones de Random son demasiado restrictivas para el uso previsto. – JeffH

+5

Tenga en cuenta que este enfoque también devuelve números negativos e Int64.MaxValue, mientras que System.Random.Next() está limitado a números positivos, incluido 0, pero sin Int32.MaxValue. –

+0

@Christoph: Sí, bien observado.Sin embargo, puedes modificar mi método con bastante facilidad para solo producir valores positivos ignorando el MSB (bit más significativo) del buffer. – Noldorin

29

Utilice 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/adición no funciona. Random.Next() solo produce enteros no negativos, es decir, genera 31 bits, no 32, por lo que el resultado de dos llamadas solo produce 62 bits aleatorios en lugar de los 64 bits requeridos para cubrir el rango completo de Int64/UInt64. (Guffa's answer muestra cómo hacerlo con tres llamadas a Random.Next() sin embargo.)

+0

Oh, buena captura (comentario) - Estoy borrando la mía, como el BitConverter etc ya está bien cubierto ... –

+0

bien - que puse en mi respuesta en lugar de sólo un comentario por lo que sería más visible. Voy a dejarlo ahora de todos modos como una advertencia para el futuro (ya que de lo contrario es una alternativa obvia). –

+0

Debido a que la mayoría de los lcm PRNG son menos aleatorios en los bits de orden baja, generar 2 números y unirlos puede introducir sutiles sesgos ... –

1

Se puede crear una matriz byte, llenarlo con datos aleatorios y luego convertirlo a long (Int64) y 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); 
3

Usted no dice cómo se va a utilizar estos números aleatorios ... tener en cuenta que los valores devueltos por aleatoria no están "criptográficamente seguro" y no deben ser utilizados para cosas involucrando (grandes) secretos o (mucho) dinero.

+0

-1 por no mencionar .Net Crypto RNG. http://msdn.microsoft.com/en-us/library/system.security.cryptography.rngcryptoserviceprovider.aspx – Samuel

+0

¿Por qué es relevante? Dan alude al hecho de que una PC no puede generar un número aleatorio criptográficamente seguro. La clase RNGCryptoServiceProvider no soluciona eso. – sipwiz

+0

No, dijo que la clase Random no puede hacerlo, no dijo nada acerca de que las computadoras no pudieran hacerlo. – Samuel

5

Siempre lo uso para obtener 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 el ruido atmosférico para generar la aleatoriedad y al parecer se utiliza para loterías y tal.

6

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

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

Aquí tienes, utiliza este el crytpo services(no la clase Random), que es (teóricamente) un RNG mejor que la clase Random. Podrías fácilmente hacer de esto una extensión de Random o crear tu 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);   
} 
+0

Esto definitivamente vale la pena señalar, aunque a juzgar por la pregunta, a la OP no parece importarle mucho la aleatoriedad de los números generados. También es importante darse cuenta de que RNGCryptoServiceProvider es * mucho * más lento que el aleatorio (aunque el rendimiento puede o no tener importancia aquí). – Noldorin

-3
Random r=new Random(); 
int j=r.next(1,23); 
Console.WriteLine(j); 
+0

la clase aleatoria se utiliza para seleccionar al azar va lues.random class le da un entorno de pozo al usuario para hacerlo –

0

Otra respuesta con RNGCryptoServiceProvider en lugar de Random. Aquí puede ver cómo eliminar el MSB para que el resultado sea siempre positivo.

public static Int64 NextInt64() 
{ 
    var buffer = new byte[8]; 
    new RNGCryptoServiceProvider().GetBytes(buffer); 
    return BitConverter.ToInt64(buffer, 0) & 0x7FFFFFFFFFFFFFFF; 
} 
Cuestiones relacionadas