Operaciones aleatorias en C#
Aprende a usar la clase Random en C# para generar números, valores y selecciones aleatorias con Next, NextDouble y ejemplos.
En C#, la clase principal para generar valores aleatorios es System.Random.
Se utiliza con frecuencia en escenarios como la mecánica de juegos, simulaciones o generación de datos de prueba.
En este artículo veremos cómo generar números con Random, definir rangos, mezclar arreglos, usar semillas (seed)
y qué hacer cuando se necesita aleatoriedad criptográficamente segura.
Uso básico: Next()
Next() genera un entero (int) no negativo. Para un rango, se usan las sobrecargas del método.
var rnd = new Random();
int a = rnd.Next(); // 0..Int32.MaxValue
int b = rnd.Next(10); // 0..9 (límite superior excluido)
int c = rnd.Next(5, 11); // 5..10 (límite inferior incluido, superior excluido)
Console.WriteLine($"{a}, {b}, {c}");
Valores decimales: NextDouble()
NextDouble() genera un número entre 0.0 y 1.0 (excluido). Puedes escalar el rango.
var rnd = new Random();
double x = rnd.NextDouble(); // [0.0, 1.0)
double y = 5.0 + rnd.NextDouble()*3; // [5.0, 8.0)
Console.WriteLine($"{x}, {y:0.000}");
Rellenar un arreglo de bytes: NextBytes()
Si se necesitan bytes aleatorios (ej. datos ficticios), se usa NextBytes.
var rnd = new Random();
byte[] buffer = new byte[8];
rnd.NextBytes(buffer);
Console.WriteLine(BitConverter.ToString(buffer)); // Ejemplo: "3F-91-0C-..."
Reproducibilidad con Semilla (Seed)
Un Random inicializado con la misma semilla genera la misma secuencia de números. Útil para pruebas.
var r1 = new Random(12345);
var r2 = new Random(12345);
Console.WriteLine(r1.Next() == r2.Next()); // True
Error común: Crear varios Random consecutivos
Crear varias veces new Random() en un corto período puede producir resultados similares/idénticos (semilla basada en la hora).
Solución: usar una sola instancia durante la aplicación o preferir Random.Shared.
// MALO
int MalaGeneracion()
{
return new Random().Next(100); // nueva instancia en cada llamada
}
// BUENO
var rnd = new Random(); // compartido
int BuenaGeneracion() => rnd.Next(100);
// .NET 6+: Random.Shared (thread-safe)
int MejorGeneracion() => Random.Shared.Next(100);
Ejemplos: Color, Estudiante, Código
var rnd = Random.Shared;
// Selección aleatoria de color
string[] colores = { "Rojo", "Azul", "Verde", "Amarillo", "Morado" };
string colorElegido = colores[rnd.Next(colores.Length)];
Console.WriteLine("Color elegido: " + colorElegido);
// Selección aleatoria de estudiante
string[] estudiantes = { "Carlos", "Lucía", "María", "Andrés", "Sofía" };
string estudianteElegido = estudiantes[rnd.Next(estudiantes.Length)];
Console.WriteLine("Estudiante elegido: " + estudianteElegido);
// Generar un código aleatorio (6 caracteres)
const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
var sb = new System.Text.StringBuilder();
for (int i = 0; i < 6; i++)
sb.Append(chars[rnd.Next(chars.Length)]);
Console.WriteLine("Código de verificación: " + sb.ToString());
Mezclar un arreglo (Fisher–Yates)
Para mezclar elementos con probabilidad uniforme, se recomienda el algoritmo Fisher–Yates.
var rnd = Random.Shared;
int[] arreglo = { 1, 2, 3, 4, 5 };
for (int i = arreglo.Length - 1; i > 0; i--)
{
int j = rnd.Next(0, i + 1); // 0..i
(arreglo[i], arreglo[j]) = (arreglo[j], arreglo[i]);
}
Console.WriteLine(string.Join(", ", arreglo));
Selección aleatoria
Elegir un elemento aleatorio de una colección:
var rnd = Random.Shared;
string[] colores = { "Rojo", "Azul", "Verde", "Amarillo" };
string eleccion = colores[rnd.Next(colores.Length)];
Console.WriteLine("Elección: " + eleccion);
Contraseña aleatoria simple (Demo)
No es criptográficamente segura; adecuada para juegos/datos de prueba. Para seguridad, usar el método de abajo.
var rnd = Random.Shared;
const string alfabeto = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
int longitud = 10;
var sb = new System.Text.StringBuilder(longitud);
for (int i = 0; i < longitud; i++)
{
int idx = rnd.Next(alfabeto.Length);
sb.Append(alfabeto[idx]);
}
Console.WriteLine("Contraseña (demo): " + sb.ToString());
Aleatoriedad criptográficamente segura
Para escenarios críticos de seguridad como generación de contraseñas, tokens o claves,
no uses Random.
En su lugar, utiliza System.Security.Cryptography.RandomNumberGenerator o los auxiliares RandomNumber.
using System.Security.Cryptography;
// 0..int.MaxValue (exclusivo)
int n1 = RandomNumberGenerator.GetInt32(int.MaxValue);
// Rango definido
int n2 = RandomNumberGenerator.GetInt32(100, 201); // 100..200
// Bytes aleatorios
byte[] key = new byte[32];
RandomNumberGenerator.Fill(key);
Console.WriteLine($"{n1}, {n2}, {BitConverter.ToString(key)}");
Nota sobre la distribución
Random produce valores cercanos a una distribución uniforme.
Para distribuciones como la normal (Gauss), se necesitan transformaciones (ej. Box–Muller) o bibliotecas estadísticas.
TL;DR
Random.Next,NextDouble,NextBytes→ API básicas.- Usa una sola instancia o
Random.Shared; no crees múltiplesnew Random(). - Misma semilla → misma secuencia de números (pruebas reproducibles).
- Para mezclar un arreglo, aplica Fisher–Yates.
- Para seguridad, usa
RandomNumberGenerator/GetInt32.