Sembrar una clase aleatoria en C#

Syed Hassan Sabeeh Kazmi 15 febrero 2024
  1. Crear una función para sembrar una clase aleatoria en C#
  2. Utilice la clase Random() para sembrar una clase aleatoria en C#
  3. Utilice la propiedad Environment.TickCount para sembrar una clase aleatoria en C#
  4. Utilice la clase RNGCryptoServiceProvider para generar una clase aleatoria en C#
Sembrar una clase aleatoria en C#

Este tutorial discutirá cómo generar una clase en C# para lograr la aleatoriedad en sus aplicaciones. Hay cuatro formas principales de inicializar una clase, y todo comienza con la clase Random que le permite generar números sin un rango específico inicializando su instancia y llamando al método Next() para obtener un número entero aleatorio y puede obtener un decimal utilizando el método NextDouble().

Puedes escribir una clase desde cero. Puede usar la clase Random, Environment.TickCount o la clase RNGCryptoServerProvider para generar una clase aleatoria en C#.

Crear una función para sembrar una clase aleatoria en C#

Cree una función como public static int random_func(int _min, int _max){} y cree un objeto de la clase Random para realizar el método Next() en los valores min y max.

Puede reiterar esta técnica creando una clase estática que contenga la función pública realizando operaciones en un objeto estático privado de la clase Random. Para un verdadero método estático sin estado, puede confiar estrictamente en un Guid para generar números aleatorios con algo como Guid.NewGuid().GetHashCode().

using System;
using System.Windows.Forms;

namespace seed_random_class {
  public partial class Form1 : Form {
    // function to get a random number
    public static int RandomNumber(int min, int max) {
      Random random = new Random();
      return random.Next(min, max);
    }
    public Form1() {
      InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e) {}

    private void label1_Click(object sender, EventArgs e) {}

    private void button1_Click(object sender, EventArgs e) {
      int min = 0;
      int max = 10;
      int return_num;
      return_num = Form1.RandomNumber(min, max);
      label1.Text = return_num.ToString();

      /* alternative approach

      byte[] _random = new byte[6];
      for (int i = 0; i < 6; ++i)
      _random[i] = (byte)(Form1.RandomNumber((int)0xFFFF, (int)0xFFFFFF) % 256);

      */
    }
  }
}

Producción:

Crear una función para sembrar una clase aleatoria

Es importante comprender que el objetivo de Guid es ser único, no uniformemente distribuido y puede ser, en la mayoría de los casos, lo opuesto a la aleatoriedad y no implementa una distribución uniforme y es por eso que crear una función basada en la clase Random es un enfoque válido . También obtendrá una mejor aleatoriedad al sembrar una clase aleatoria con un número impredecible más grande como Random((int)DateTime.Now.Ticks).

Utilice la clase Random() para sembrar una clase aleatoria en C#

Crear una instancia de la clase Random y aplicar el método Next() en esa instancia en un bucle siempre es la mejor manera de generar las clases en C#. Los números que genera una sola instancia de clase Random siempre se distribuyen uniformemente, y puede sembrarlos con valores idénticos para generar números aleatorios idénticos creando una nueva instancia de clase Random para cada número aleatorio en rápida sucesión.

Es una gran práctica volver a sembrar una clase Random en aras de la integridad y crear una nueva instancia a partir de la nueva semilla y volver a sembrar es una gran opción cuando la previsibilidad se convierte en un problema, y además de usar un generador aleatorio más verdadero, debe volver a sembrar más rápido de lo que se puede aplicar el reconocimiento de patrones desde el lado del atacante y puede asegurarse de que no se sembraron dos generadores con los mismos valores.

El nuevo Random() siempre se inicializa usando el reloj del sistema, lo que significa que puede obtener los mismos valores. Por lo tanto, debe mantener una sola instancia Random y seguir usando el método Next() en la misma instancia.

using System;
using System.Windows.Forms;

namespace seed_random_class {
  public partial class Form1 : Form {
    public Form1() {
      InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e) {}

    private void label1_Click(object sender, EventArgs e) {}

    private void button1_Click(object sender, EventArgs e) {
      var _random = new Random();
      for (int i = 0; i < 100; ++i) label1.Text = _random.Next(1, 100).ToString();
    }
  }
}

Producción:

Use la clase Random() para sembrar una clase aleatoria

Lo más importante es que necesita un bloqueo para sincronizar la semilla con Siguiente() porque si aplica Siguiente() al mismo tiempo a varios subprocesos, puede hacer que el resultado sea aún más aleatorio, y hacerlo puede romper potencialmente la implementación interna. El bloqueo garantiza la seguridad del subproceso, y la sincronización es el mejor enfoque para lograr la máxima aleatoriedad.

Usar lock con una instancia de clase Random es una alternativa pero menos segura para subprocesos que la otra. Supongamos que está utilizando un hilo y un constructor sin parámetros del objeto Random.

En ese caso, puede enfrentar un retraso causado por llamar al método Thread.Sleep que conduce a producir un valor semilla diferente para ese objeto y puede generar una secuencia diferente de números aleatorios.

Utilice la propiedad Environment.TickCount para sembrar una clase aleatoria en C#

Pertenece al espacio de nombres Sistema y tiene importancia para obtener la cantidad de milisegundos desde que se inició el sistema y representa un entero de 32 bits con signo. Esta propiedad alterna entre Int32.MinValue e Int32.MaxValue que representan números negativos y positivos respectivamente, y puede eliminar el bit de signo para producir un número no negativo que alterna entre cero y el valor positivo máximo una vez cada 24.9 días. .

La resolución de su entero con signo de 32 bits está limitada a la resolución del temporizador de su sistema que oscila entre 10 y 16 milisegundos. Lo que es más importante, la implementación utilizada por System.Random es Environment.TickCount y evita tener que convertir DateTime.UtcNow.Ticks y puede facilitar la reutilización de la inicialización de clases aleatorias en toda su aplicación C#.

using System;
using System.Threading;  // essential namespace for threading
using System.Windows.Forms;

namespace seed_random_class {
  public static class StaticRandom {
    // initialize the seed
    private static int _var_seed;

    // a thread-safe approach to access the random class via seed
    // `<Random>` implies the Random class
    private static ThreadLocal<Random> local_thread =
        new ThreadLocal<Random>(() => new Random(Interlocked.Increment(ref _var_seed)));

    // method that utilizes the `Environment.TickCount` property
    static StaticRandom() {
      _var_seed = Environment.TickCount;
    }

    public static Random class_inst {
      get { return local_thread.Value; }
    }
  }
  public partial class Form1 : Form {
    public Form1() {
      InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e) {}

    private void label1_Click(object sender, EventArgs e) {}

    private void button1_Click(object sender, EventArgs e) {
      label1.Text = StaticRandom.class_inst.Next(1, 100).ToString();
    }
  }
}

Producción:

Use la propiedad Environment.TickCount para sembrar una clase aleatoria

Utilice la clase RNGCryptoServiceProvider para generar una clase aleatoria en C#

En algunos casos únicos, se vuelve necesario usar la clase RNGCryptoServerProver. Pertenece al espacio de nombres System.Security.Cryptography e implementa un RNG criptográfico (Generador de números aleatorios) utilizando la implementación proporcionada por el CSP (Proveedor de servicios criptográficos) y no se puede heredar.

Es importante deshacerse de él directa o indirectamente porque implementa la interfaz IDisposable, y puede llamar al método Dispose en un bloque try/catch. En C#, puede usar la construcción using para deshacerse de ella y crear una semilla perfecta para su clase aleatoria.

La clase System.Security.Cryptography.RNGCryptoServiceProvider es segura para subprocesos y satisface una necesidad genuina al reproducir valores de una semilla conocida. Sin embargo, es matemáticamente imposible crear una función que pueda generar dos valores independientes, y esto también implica que cualquier esquema criptográfico no es completamente seguro y, a veces, el costo total de usarlo puede ser demasiado.

using System;
using System.Windows.Forms;

namespace seed_random_class {
  public partial class Form1 : Form {
    public Form1() {
      InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e) {}

    private void label1_Click(object sender, EventArgs e) {}

    private void button1_Click(object sender, EventArgs e) {
      byte[] foo = { 0x32, 0x00, 0x1E, 0x00 };
      System.Security.Cryptography.RNGCryptoServiceProvider prov =
          new System.Security.Cryptography.RNGCryptoServiceProvider();
      prov.GetBytes(foo);
    }
  }
}

Producción:

Use la clase RNGCryptoServiceProvider para generar una clase aleatoria

Puede usar los métodos Next(int) o Next(int min, int max) para generar números aleatorios en el rango o puede usar Next() y NextBytes() para generar respectivamente números enteros y series aleatorios de valores de bytes. O proporciona una semilla a través de la sobrecarga del constructor, o el marco se encargará de esto por usted.

Es un enfoque costoso para instanciar la clase Random y exagerar puede disminuir el rendimiento de sus aplicaciones C#; en su lugar, crea una única instancia Random y llama al método Next() varias veces. La criptografía es un enfoque más seguro y protector para generar una clase aleatoria en C#.

Syed Hassan Sabeeh Kazmi avatar Syed Hassan Sabeeh Kazmi avatar

Hassan is a Software Engineer with a well-developed set of programming skills. He uses his knowledge and writing capabilities to produce interesting-to-read technical articles.

GitHub

Artículo relacionado - Csharp Math