numeros - numero aleatorio en un rango c#
¿Cómo genero un número int aleatorio en C#? (27)
¿Cómo genero un entero aleatorio en C #?
¿Por qué no usar int randomNumber = Random.Range(start_range, end_range)
?
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 de los lenguajes de programación, incluidos C # y C ++, no se baraja correctamente antes de usarlos. Esto significa que obtendrá el mismo número una y otra vez, lo que no es realmente aleatorio. Para evitar dibujar el mismo número una y otra vez, necesitas una semilla. Normalmente, las garrapatas en el tiempo están bien para esta tarea. Recuerde que obtendrá el mismo número una y otra vez si utiliza la misma semilla cada vez. Así que trata de usar semillas variadas siempre. El tiempo es una buena fuente para la semilla porque siempre cambian.
int GetRandomNumber(int min, int max)
{
Random rand = new Random((int)DateTime.Now.Ticks);
return rand.Next(min, max);
}
Si está buscando un generador de números aleatorios para la distribución normal, puede usar una transformación de Box-Muller. Verifique la respuesta de yoyoyoyosef en la pregunta de variable gaussiana aleatoria. Como desea un entero, tiene que convertir el valor doble en un entero al final.
Random rand = new Random(); //reuse this if you are generating many
double u1 = 1.0-rand.NextDouble(); //uniform(0,1] random doubles
double u2 = 1.0-rand.NextDouble();
double randStdNormal = Math.Sqrt(-2.0 * Math.Log(u1)) *
Math.Sin(2.0 * Math.PI * u2); //random normal(0,1)
double randNormal =
mean + stdDev * randStdNormal; //random normal(mean,stdDev^2)
Cada vez que haces un nuevo Random () se inicializa. Esto significa que en un circuito cerrado obtienes el mismo valor muchas veces. Debe mantener una sola instancia aleatoria y seguir usando Siguiente en la misma instancia.
//Function to get random number
private static readonly Random getrandom = new Random();
public static int GetRandomNumber(int min, int max)
{
lock(getrandom) // synchronize
{
return getrandom.Next(min, max);
}
}
Esta es la clase que uso. Funciona como RandomNumber.GenerateRandom(1, 666)
internal static class RandomNumber
{
private static Random r = new Random();
private static object l = new object();
private static Random globalRandom = new Random();
[ThreadStatic]
private static Random localRandom;
public static int GenerateNewRandom(int min, int max)
{
return new Random().Next(min, max);
}
public static int GenerateLockedRandom(int min, int max)
{
int result;
lock (RandomNumber.l)
{
result = RandomNumber.r.Next(min, max);
}
return result;
}
public static int GenerateRandom(int min, int max)
{
Random random = RandomNumber.localRandom;
if (random == null)
{
int seed;
lock (RandomNumber.globalRandom)
{
seed = RandomNumber.globalRandom.Next();
}
random = (RandomNumber.localRandom = new Random(seed));
}
return random.Next(min, max);
}
}
He intentado todas estas soluciones excluyendo la respuesta COBOL ... lol
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 demasiado largos, 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.
public int GenerateRandom(int min, int max)
{
var seed = Convert.ToInt32(Regex.Match(Guid.NewGuid().ToString(), @"/d+").Value);
return new Random(seed).Next(min, max);
}
Actualización : la siembra no es necesaria si crea una instancia de la clase Random una vez. Por lo tanto, sería mejor crear una clase estática y cancelar un método.
public static class IntUtil
{
private static Random random;
private static void Init()
{
if (random == null) random = new Random();
}
public static int Random(int min, int max)
{
Init();
return random.Next(min, max);
}
}
Entonces puedes usar la clase estática así ...
for(var i = 0; i < 1000; i++)
{
int randomNumber = IntUtil.Random(1,100);
Console.WriteLine(randomNumber);
}
Admito que me gusta más este enfoque.
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 criptografía RNG. Pero luego cuándo elegir qué.
Para eso necesitamos entender primero el término ALEATORIA y la filosofía detrás de él.
Le animo a ver este video que profundiza en la filosofía de RANDOMNESS utilizando C # https://www.youtube.com/watch?v=tCYxc-2-3fY
En primer lugar, entendamos la filosofía de la ALEATORIA. Cuando le decimos a una persona que elija entre ROJO, VERDE y AMARILLO, lo que sucede internamente. ¿Qué hace que una persona elija ROJO o AMARILLO o VERDE?
Algún pensamiento inicial se dirige a la mente de la persona que decide su elección, puede ser el color favorito, el color de la suerte, etc. En otras palabras, un disparador inicial que denominamos RANDOM como SEED. Este SEED es el punto de inicio, el disparador que lo incita a seleccionar el valor RANDOM.
Ahora bien, si una SEMILLA es fácil de adivinar, entonces ese tipo de números aleatorios se denomina PSEUDO y cuando una semilla es difícil de adivinar esos números aleatorios se denominan NÚMEROS aleatorios SEGUROS .
Por ejemplo, una persona elige el color dependiendo de la combinación de clima y sonido, entonces sería difícil adivinar la semilla inicial.
Ahora déjame hacer una declaración importante:
* La clase "Aleatoria" genera solo el número aleatorio de PSEUDO y para generar un número aleatorio SEGURO necesitamos usar la clase "RNGCryptoServiceProvider".
La clase aleatoria toma valores semilla de su reloj de CPU, lo cual es muy predecible. Entonces, en otras palabras, la clase RANDOM de C # genera números pseudoaleatorios, a continuación se muestra el código para el mismo.
Random rnd= new Random();
int rndnumber = rnd.Next()
Mientras que la clase RNGCryptoServiceProvider utiliza 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 ratón y los tiempos del teclado, la temperatura térmica, etc. A continuación se muestra el código para el mismo.
using (RNGCryptoServiceProvider rg = new RNGCryptoServiceProvider())
{
byte[] rno = new byte[5];
rg.GetBytes(rno);
int randomvalue = BitConverter.ToInt32(rno, 0);
}
Para entender la entropía del SO, 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 SO. Entonces, al poner en palabras simples RNG Crypto genera números aleatorios SEGUROS.
Los números calculados por una computadora a través de un proceso determinista no pueden, por definición, ser aleatorios.
Si desea un número aleatorio genuino, la aleatoriedad proviene del ruido atmosférico o la desintegración radioactiva.
Puedes probar por ejemplo RANDOM.ORG (reduce el rendimiento)
Los números generados por la clase Random
incorporada (System.Random) generan números pseudoaleatorios.
Si desea obtener verdaderos números aleatorios, lo más cercano que podemos obtener es el "Generador pseudoaleatorio seguro", que puede generarse mediante el uso de clases criptográficas en C #, como RNGCryptoServiceProvider
.
Aun así, si aún necesita verdaderos números aleatorios, necesitará usar una fuente externa, como dispositivos que tengan en cuenta 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.
Para semillas aleatorias fuertes, siempre uso CryptoRNG y no Time.
using System;
using System.Security.Cryptography;
public class Program
{
public static void Main()
{
var random = new Random(GetSeed());
Console.WriteLine(random.Next());
}
public static int GetSeed()
{
using (var rng = new RNGCryptoServiceProvider())
{
var intBytes = new byte[4];
rng.GetBytes(intBytes);
return BitConverter.ToInt32(intBytes, 0);
}
}
}
Podría usar el método StaticRandom Jon Skeet dentro de la biblioteca de clases MiscUtil que construyó para un número pseudoaleatorio.
using System;
using MiscUtil;
class Program
{
static void Main(string[] args)
{
for (int i = 0; i < 100; i++)
{
Console.WriteLine(StaticRandom.Next());
}
}
}
Pruebe estos simples pasos para crear números aleatorios:
Crear función:
private int randomnumber(int min, int max)
{
Random rnum = new Random();
return rnum.Next(min, max);
}
Use la función anterior en una ubicación donde desee usar números aleatorios. Supongamos que desea utilizarlo en un cuadro de texto.
textBox1.Text = randomnumber(0, 999).ToString();
0 es min y 999 es max. Puedes cambiar los valores a lo que quieras.
Puedes probar con el valor semilla aleatorio usando a continuación:
var rnd = new Random(11111111); //note: seed value is 11111111
string randomDigits = rnd.Next().ToString().Substring(0, 8);
var requestNumber = $"SD-{randomDigits}";
Quería agregar una versión criptográficamente segura:
Clase RNGCryptoServiceProvider ( MSDN o dotnetperls )
Implementa IDisposable.
using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider())
{
byte[] randomNumber = new byte[4];//4 for int32
rng.GetBytes(randomNumber);
int value = BitConverter.ToInt32(randomNumber, 0);
}
Quería demostrar lo que sucede cuando se usa un nuevo generador aleatorio cada vez. Supongamos que tiene dos métodos o dos clases que requieren un número aleatorio. Y ingenuamente los codificas como:
public class A
{
public A()
{
var rnd=new Random();
ID=rnd.Next();
}
public int ID { get; private set; }
}
public class B
{
public B()
{
var rnd=new Random();
ID=rnd.Next();
}
public int ID { get; private set; }
}
¿Crees que obtendrás dos identificaciones diferentes? NOPE
class Program
{
static void Main(string[] args)
{
A a=new A();
B b=new B();
int ida=a.ID, idb=b.ID;
// ida = 1452879101
// idb = 1452879101
}
}
La solución es usar siempre un único generador aleatorio estático. Me gusta esto:
public static class Utils
{
public static readonly Random random=new Random();
}
public class A
{
public A()
{
ID=Utils.random.Next();
}
public int ID { get; private set; }
}
public class B
{
public B()
{
ID=Utils.random.Next();
}
public int ID { get; private set; }
}
Rápido y fácil para en línea, utilice el siguiente código:
new Random().Next(min, max);
// for example unique name
strName += "_" + new Random().Next(100, 999);
Respuesta modificada desde here .
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/
Solo descargue la última versión desde here , incluya Jebtek.RdRand y agregue una declaración de uso para ello. Entonces, todo lo que necesitas hacer es esto:
bool isAvailable = RdRandom.GeneratorAvailable(); //Check to see if this is a compatible CPU
string key = RdRandom.GenerateKey(10); //Generate 10 random characters
string apiKey = RdRandom.GenerateAPIKey(); //Generate 64 random characters, useful for API keys
byte[] b = RdRandom.GenerateBytes(10); //Generate an array of 10 random bytes
uint i = RdRandom.GenerateUnsignedInt() //Generate a random unsigned int
Si no tiene una CPU compatible para ejecutar el código, solo use los servicios RESTful en rdrand.com. Con la biblioteca de envoltorio de RdRandom incluida en su proyecto, solo tendría que hacer esto (obtendrá 1000 llamadas gratis cuando se registre):
string ret = Randomizer.GenerateKey(<length>, "<key>");
uint ret = Randomizer.GenerateUInt("<key>");
byte[] ret = Randomizer.GenerateBytes(<length>, "<key>");
Si bien esto está bien:
Random random = new Random();
int randomNumber = random.Next()
Desearía controlar el límite (mínimo y máximo de números) la mayor parte del tiempo. Por lo tanto, debe especificar dónde comienza y termina el número aleatorio.
El método Next()
acepta dos parámetros, min y max.
Así que si quiero que mi número aleatorio esté entre, digamos, 5 y 15, simplemente lo haría
int randomNumber = random.Next(5, 16)
Siempre tengo métodos que generan números aleatorios que ayudan para varios propósitos. Espero que esto te pueda ayudar también
public class RandomGenerator
{
public int RandomNumber(int min, int max)
{
Random random = new Random();
return random.Next(min, max);
}
public string RandomString(int size, bool lowerCase)
{
StringBuilder builder = new StringBuilder();
Random random = new Random();
char ch;
for (int i = 0; i < size; i++)
{
ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));
builder.Append(ch);
}
if (lowerCase)
return builder.ToString().ToLower();
return builder.ToString();
}
}
Tenga en cuenta que el new Random()
se siembra en la marca de tiempo actual.
Si quieres generar un solo número puedes usar:
new Random().Next( int.MinValue, int.MaxValue )
Para obtener más información, consulte la clase Random , aunque tenga en cuenta:
Sin embargo, debido a que el reloj tiene una resolución finita, el uso del constructor sin parámetros para crear diferentes objetos aleatorios en una sucesión cercana crea generadores de números aleatorios que producen secuencias idénticas de números aleatorios
Por lo tanto, no utilice este código para generar una serie de números aleatorios.
Usa una instancia de Random repetidamente
// Somewhat better code...
Random rng = new Random();
for (int i = 0; i < 100; i++)
{
Console.WriteLine(GenerateDigit(rng));
}
...
static int GenerateDigit(Random rng)
{
// Assume there''d be more logic here really
return rng.Next(10);
}
Este artículo analiza por qué la aleatoriedad causa tantos problemas y cómo abordarlos. http://csharpindepth.com/Articles/Chapter12/Random.aspx
Yo uso el siguiente código para tener un número aleatorio:
var random = new Random((int)DateTime.Now.Ticks);
var randomValue = random.Next(startValue, endValue + 1);
es mejor sembrar el objeto aleatorio con los milisegundos actuales, para asegurar un verdadero número aleatorio, y casi no encontrará duplicados usándolo muchas veces
Random rand = new Random(DateTime.Now.Millisecond);
Actualizar
Sé que new Random()
usa los ticks actuales como semilla, pero sembrar con los milisegundos actuales sigue siendo lo suficientemente bueno ya que es un buen inicio aleatorio
El último punto restante es que no tiene que inicializar new Random()
cada vez que necesite un número aleatorio, inicie un objeto Random y utilícelo tantas veces como lo necesite dentro de un bucle o lo que sea
La clase Random
se utiliza para crear números aleatorios. (Pseudo-aleatorio que es, 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 instancia Random
y reutilizarla. Si creas nuevas instancias demasiado cercanas en el tiempo, producirán la misma serie de números aleatorios, ya que el generador aleatorio se siembra del reloj del sistema.
int n = new Random().Next();
También puede dar un valor mínimo y máximo a la función Next()
. Me gusta
int n = new Random().Next(5,10);
Random r = new Random();
int n = r.Next();
Random rand = new Random();
int name = rand.Next()
Ponga los valores que desee en los segundos paréntesis, asegúrese de haber establecido un nombre escribiendo prop y doble pestaña para generar el código
Random random = new Random ();
int randomNumber = random.Next (lowerBound,upperBound);