¿Cómo genero un entero aleatorio en C #?
1922
La Random
clase se usa para crear números aleatorios. (Pseudoaleatorio, por supuesto).
Ejemplo:
Random rnd = new Random();
int month = rnd.Next(1, 13); // creates a number between 1 and 12
int dice = rnd.Next(1, 7); // creates a number between 1 and 6
int card = rnd.Next(52); // creates a number between 0 and 51
Si va a crear más de un número aleatorio, debe conservar la Random
instancia y reutilizarla. Si crea nuevas instancias demasiado cercanas en el tiempo, producirán la misma serie de números aleatorios que el generador aleatorio se siembra desde el reloj del sistema.
rnd
comostatic
y / o configurarlo sólo una vez al inicializar el código.Random
...Random
que su aleatoriedad sea más robusta: ericlippert.com/2019/02/04/fixing-random-part-2 y codeblog.jonskeet.uk/2009/11/04/revisiting Aleatoriedad .La pregunta parece muy simple pero la respuesta es un poco complicada. Si ve que casi todos han sugerido usar la clase Random y algunos han sugerido usar la clase de cifrado RNG. Pero luego cuándo elegir qué.
Para eso necesitamos primero entender el término ALEATORIO y la filosofía detrás de él.
Te animo a ver este video que profundiza en la filosofía de RANDOMNESS utilizando C # https://www.youtube.com/watch?v=tCYxc-2-3fY
Lo primero es que entendamos la filosofía del ALEATORIO. Cuando le decimos a una persona que elija entre ROJO, VERDE y AMARILLO lo que sucede internamente. ¿Qué hace que una persona elija ROJO, AMARILLO o VERDE?
Un pensamiento inicial entra en la mente de las personas que decide su elección, puede ser el color favorito, el color de la suerte, etc. En otras palabras, un disparador inicial que denominamos en RANDOM como SEED. Este SEED es el punto de inicio, el disparador que lo instiga a seleccionar el valor RANDOM.
Ahora bien, si una SEMILLA es fácil de adivinar, ese tipo de números aleatorios se denominan PSEUDO y cuando una semilla es difícil de adivinar, esos números aleatorios se denominan SEGURO números aleatorios .
Por ejemplo, una persona elige su color dependiendo del clima y la combinación de sonido, entonces sería difícil adivinar la semilla inicial.
Ahora déjame hacer una declaración importante:
* La clase "Random" genera solo un número aleatorio PSEUDO y para generar un número aleatorio SEGURO necesitamos usar la clase "RNGCryptoServiceProvider".
La clase aleatoria toma valores iniciales del reloj de su CPU, lo cual es muy predecible. En otras palabras, la clase RANDOM de C # genera números pseudoaleatorios, a continuación se muestra el código para el mismo.
** Nota: **
.NET Core 2.0.0+
usa una semilla diferente en el constructor sin parámetros: en lugar del reloj de la CPU, usaGuid.NewGuid().GetHashCode()
.Mientras que la
RNGCryptoServiceProvider
clase usa la entropía del sistema operativo para generar semillas. La entropía del sistema operativo es un valor aleatorio que se genera mediante el sonido, el clic del mouse y los tiempos del teclado, la temperatura térmica, etc. A continuación se muestra el código correspondiente.Para comprender la entropía del sistema operativo, vea este video de 14:30 https://www.youtube.com/watch?v=tCYxc-2-3fY donde se explica la lógica de la entropía del sistema operativo. Entonces, en palabras simples, RNG Crypto genera números aleatorios SEGUROS.
fuente
RandomNumberGenerator.Create()
lugar de llamar al constructor de,RNGCryptoServiceProvider
ya que no está disponible en todas las plataformas.Cada vez que haces un nuevo Random () se inicializa. Esto significa que en un ciclo cerrado obtienes el mismo valor muchas veces. Debe mantener una única instancia aleatoria y seguir usando Siguiente en la misma instancia.
fuente
Random
objeto. En ambos casos obtuve el mismo número aleatorio. Con el acercamiento de Pankaj no sucedió. Quizás esto sea aleatorio , pero lo dudo ahora. Estoy buscando el número aleatorio en el mismo segundo de diferentes hilos.Tenga en cuenta que
new Random()
se siembra en la marca de tiempo actual.Si desea generar solo un número , puede usar:
new Random().Next( int.MinValue, int.MaxValue )
Para obtener más información, mire la clase Aleatoria , aunque tenga en cuenta:
Por lo tanto, no use este código para generar una serie de números aleatorios.
fuente
new Random()
en un bucle es un punto importante.fuente
Quería agregar una versión criptográficamente segura:
Clase RNGCryptoServiceProvider ( MSDN o dotnetperls )
Implementa IDisposable.
fuente
Podría usar el método StaticRandom de Jon Skeet dentro de la biblioteca de clases MiscUtil que creó para un número pseudoaleatorio.
fuente
He probado todas estas soluciones, excepto la respuesta COBOL ... jajaja
Ninguna de estas soluciones fue lo suficientemente buena. Necesitaba randoms en un bucle rápido para int y estaba obteniendo toneladas de valores duplicados incluso en rangos muy amplios. Después de conformarme con resultados aleatorios durante demasiado tiempo, decidí finalmente abordar este problema de una vez por todas.
Se trata de la semilla.
Creo un entero aleatorio analizando los no dígitos de Guid, luego lo uso para crear una instancia de mi clase Aleatoria.
Actualización : la siembra no es necesaria si crea una instancia de la clase Aleatoria una vez. Por lo tanto, sería mejor crear una clase estática y desactivar un método.
Entonces puedes usar la clase estática así ...
Admito que me gusta más este enfoque.
fuente
Los números generados por la
Random
clase incorporada (System.Random) generan números pseudoaleatorios.Si desea números aleatorios verdaderos, lo más cercano que podemos obtener es un "generador de pseudoaleatorio seguro" que se puede generar utilizando las clases criptográficas en C # como
RNGCryptoServiceProvider
.Aun así, si todavía necesita números aleatorios verdaderos , necesitará usar una fuente externa como dispositivos que representan la desintegración radiactiva como semilla para un generador de números aleatorios. Dado que, por definición, cualquier número generado por medios puramente algorítmicos no puede ser verdaderamente aleatorio.
fuente
crear un objeto aleatorio
y úsalo
no tiene que inicializar
new Random()
cada vez que necesita un número aleatorio, inicie uno aleatorio y luego utilícelo tantas veces como lo necesite dentro de un ciclo o lo que seafuente
new Random()
usa las garrapatas actuales como semilla. Cuando crea una instancia de varias instancias dentro del mismo milisegundo (en lugar de marcar), obtendrá el mismo valor devuelto.Respuesta modificada desde aquí .
Si tiene acceso a una CPU compatible con Intel Secure Key, puede generar números y cadenas aleatorios reales utilizando estas bibliotecas: https://github.com/JebteK/RdRand y https://www.rdrand.com/
Simplemente descargue la última versión desde aquí , incluya Jebtek.RdRand y agregue una declaración de uso para ello. Entonces, todo lo que necesitas hacer es esto:
Si no tiene una CPU compatible para ejecutar el código, simplemente use los servicios RESTful en rdrand.com. Con la biblioteca de envoltura RdRandom incluida en su proyecto, solo necesitaría hacer esto (recibe 1000 llamadas gratis cuando se registra):
fuente
Usé el siguiente código para tener un número aleatorio (no recomendado):
fuente
Si bien esto está bien:
Desea controlar el límite (números mínimos y máximos) la mayor parte del tiempo. Por lo tanto, debe especificar dónde comienza y termina el número aleatorio.
El
Next()
método acepta dos parámetros, min y max.Entonces, si quiero que mi número aleatorio esté entre digamos 5 y 15, simplemente haría
fuente
Esta es la clase que uso. Funciona como
RandomNumber.GenerateRandom(1, 666)
fuente
Quería demostrar lo que sucede cuando se usa un nuevo generador aleatorio cada vez. Suponga que tiene dos métodos o dos clases, cada una de las cuales requiere un número aleatorio. E ingenuamente los codifica como:
¿Crees que obtendrás dos ID diferentes? NOPE
La solución es usar siempre un único generador aleatorio estático. Me gusta esto:
fuente
RNGCryptoServiceProvider
es una mejor opción de todos modos.Para semilla aleatoria fuerte siempre uso CryptoRNG y no Time.
fuente
fuente
Solo como una nota para referencia futura.
Si está utilizando .NET Core, varias instancias aleatorias no son tan peligrosas como antes. Soy consciente de que esta pregunta es de 2010, pero como esta pregunta es antigua pero tiene cierta atracción, creo que es bueno documentar el cambio.
Puede consultar esta pregunta que hice hace un tiempo:
¿Microsoft cambió la semilla predeterminada aleatoria?
Básicamente, han cambiado la semilla predeterminada de
Environment.TickCount
aGuid.NewGuid().GetHashCode()
, por lo que si crea 2 instancias de Aleatorio, no mostrará los mismos números.Puede ver el archivo difiere de .NET Framework / .NET Core (2.0.0+) aquí: https://github.com/dotnet/coreclr/pull/2192/commits/9f6a0b675e5ac0065a268554de49162c539ff66d
No es tan seguro como RNGCryptoServiceProvider, pero al menos no le dará resultados extraños.
fuente
Interop.GetRandomBytes((byte*)&result, sizeof(int));
.Los números calculados por una computadora a través de un proceso determinista no pueden, por definición, ser aleatorios.
Si desea números aleatorios genuinos, la aleatoriedad proviene del ruido atmosférico o la desintegración radiactiva.
Puede probar, por ejemplo, RANDOM.ORG (reduce el rendimiento)
fuente
Ponga los valores que desee en el segundo paréntesis, asegúrese de haber establecido un nombre escribiendo prop y doble tabulación para generar el código
fuente
Si desea que un CSRNG genere números aleatorios entre un mínimo y un máximo, esto es para usted. Inicializará las
Random
clases con semillas aleatorias seguras.fuente
Lo sentimos, OP realmente requiere un
int
valor aleatorio , pero con el simple propósito de compartir conocimiento si desea unBigInteger
valor aleatorio , puede usar la siguiente declaración:fuente
Asumiré que desea un generador de números aleatorios distribuido uniformemente como se muestra a continuación. El número aleatorio en la mayoría del lenguaje de programación, incluidos C # y C ++, no se mezcla correctamente antes de usarlos. Esto significa que obtendrá el mismo número una y otra vez, lo cual no es realmente aleatorio. Para evitar dibujar el mismo número una y otra vez, necesita una semilla. Por lo general, los tics en el tiempo están bien para esta tarea. Recuerde que obtendrá el mismo número una y otra vez si usa la misma semilla cada vez. Así que trate de usar semillas variadas siempre. El tiempo es una buena fuente de semillas porque siempre cambian.
Si está buscando un generador de números aleatorios para una distribución normal, puede usar una transformación Box-Muller. Comprueba la respuesta de yoyoyoyosef en Random Gaussian Variable Question. Como desea un número entero, debe emitir un valor doble al número entero al final.
Variables gaussianas aleatorias
fuente
La forma más fácil es probablemente solo
Random.range(1, 3)
Esto generaría un número entre 1 y 2.fuente
Puede probar con un valor de semilla aleatorio usando a continuación:
fuente
¿Por qué no usar
int randomNumber = Random.Range(start_range, end_range)
?fuente
Use una instancia de Aleatorio repetidamente
Este artículo analiza por qué la aleatoriedad causa tantos problemas y cómo abordarlos. http://csharpindepth.com/Articles/Chapter12/Random.aspx
fuente
Random
no es una clase segura para subprocesos. Si crea una única instancia, debe restringir el acceso a ella detrás de un mecanismo de bloqueo.Pruebe estos sencillos pasos para crear números aleatorios:
Crear función:
Use la función anterior en una ubicación donde desee usar números aleatorios. Suponga que desea usarlo en un cuadro de texto.
0 es mínimo y 999 es máximo. Puede cambiar los valores a lo que quiera.
fuente
Siempre tengo métodos que generan números aleatorios que ayudan para varios propósitos. Espero que esto también te pueda ayudar:
fuente
Rápido y fácil para en línea, use el siguiente código:
fuente