Respuestas:
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
como static
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()
.
var random = new Random();
int randomnumber = random.Next()
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.
using (RNGCryptoServiceProvider rg = new RNGCryptoServiceProvider())
{
byte[] rno = new byte[5];
rg.GetBytes(rno);
int randomvalue = BitConverter.ToInt32(rno, 0);
}
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.
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.
//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);
}
}
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:
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 sucesión cercana crea generadores de números aleatorios que producen secuencias idénticas de números aleatorios
Por lo tanto, no use este código para generar una serie de números aleatorios.
new Random()
en un bucle es un punto importante.
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);
}
Podría usar el método StaticRandom de Jon Skeet dentro de la biblioteca de clases MiscUtil que creó para un número pseudoaleatorio.
using MiscUtil;
...
for (int i = 0; i < 100;
Console.WriteLine(StaticRandom.Next());
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.
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 Aleatoria una vez. Por lo tanto, sería mejor crear una clase estática y desactivar 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.
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.
crear un objeto aleatorio
Random rand = new Random();
y úsalo
int randomNumber = rand.Next(min, max);
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 sea
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:
// Check to see if this is a compatible CPU
bool isAvailable = RdRandom.GeneratorAvailable();
// Generate 10 random characters
string key = RdRandom.GenerateKey(10);
// Generate 64 random characters, useful for API keys
string apiKey = RdRandom.GenerateAPIKey();
// Generate an array of 10 random bytes
byte[] b = RdRandom.GenerateBytes(10);
// Generate a random unsigned int
uint i = RdRandom.GenerateUnsignedInt();
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):
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()
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
int randomNumber = random.Next(5, 16)
Esta es la clase que uso. Funciona comoRandomNumber.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);
}
}
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:
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 ID 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; }
}
RNGCryptoServiceProvider
es una mejor opción de todos modos.
Para semilla aleatoria fuerte 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);
}
}
}
Random random = new Random ();
int randomNumber = random.Next (lowerBound,upperBound);
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
a Guid.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.
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)
Random rand = new Random();
int name = rand.Next()
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
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.
class SecureRandom : Random
{
public static byte[] GetBytes(ulong length)
{
RNGCryptoServiceProvider RNG = new RNGCryptoServiceProvider();
byte[] bytes = new byte[length];
RNG.GetBytes(bytes);
RNG.Dispose();
return bytes;
}
public SecureRandom() : base(BitConverter.ToInt32(GetBytes(4), 0))
{
}
public int GetRandomInt(int min, int max)
{
int treashold = max - min;
if(treashold != Math.Abs(treashold))
{
throw new ArithmeticException("The minimum value can't exceed the maximum value!");
}
if (treashold == 0)
{
throw new ArithmeticException("The minimum value can't be the same as the maximum value!");
}
return min + (Next() % treashold);
}
public static int GetRandomIntStatic(int min, int max)
{
int treashold = max - min;
if (treashold != Math.Abs(treashold))
{
throw new ArithmeticException("The minimum value can't exceed the maximum value!");
}
if(treashold == 0)
{
throw new ArithmeticException("The minimum value can't be the same as the maximum value!");
}
return min + (BitConverter.ToInt32(GetBytes(4), 0) % treashold);
}
}
Lo sentimos, OP realmente requiere un int
valor aleatorio , pero con el simple propósito de compartir conocimiento si desea un BigInteger
valor aleatorio , puede usar la siguiente declaración:
BigInteger randomVal = BigInteger.Abs(BigInteger.Parse(Guid.NewGuid().ToString().Replace("-",""), NumberStyles.AllowHexSpecifier));
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.
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 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.
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)
La forma más fácil es probablemente solo Random.range(1, 3)
Esto generaría un número entre 1 y 2.
Puede probar con un valor de semilla aleatorio usando a continuación:
var rnd = new Random(11111111); //note: seed value is 11111111
string randomDigits = rnd.Next();
var requestNumber = $"SD-{randomDigits}";
¿Por qué no usar int randomNumber = Random.Range(start_range, end_range)
?
Use una instancia de Aleatorio 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
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:
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. Suponga que desea usarlo en un cuadro de texto.
textBox1.Text = randomnumber(0, 999).ToString();
0 es mínimo y 999 es máximo. Puede cambiar los valores a lo que quiera.
Siempre tengo métodos que generan números aleatorios que ayudan para varios propósitos. Espero que esto también te pueda ayudar:
public class RandomGenerator
{
public int RandomNumber(int min, int max)
{
var random = new Random();
return random.Next(min, max);
}
public string RandomString(int size, bool lowerCase)
{
var builder = new StringBuilder();
var 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();
}
}
Rápido y fácil para en línea, use el siguiente código:
new Random().Next(min, max);
// for example unique name
strName += "_" + new Random().Next(100, 999);