Seed eine zufällige Klasse in C#

Syed Hassan Sabeeh Kazmi 15 Februar 2024
  1. Erstellen Sie eine Funktion zum Seeding einer zufälligen Klasse in C#
  2. Verwenden Sie die Klasse Random(), um eine zufällige Klasse in C# zu erstellen
  3. Verwenden Sie die Eigenschaft Environment.TickCount, um eine zufällige Klasse in C# zu erstellen
  4. Verwenden Sie die Klasse RNGCryptoServiceProvider, um eine zufällige Klasse in C# zu erstellen
Seed eine zufällige Klasse in C#

In diesem Tutorial wird erläutert, wie Sie eine Klasse in C# säen, um Zufälligkeit in Ihren Anwendungen zu erreichen. Es gibt vier primäre Möglichkeiten, eine Klasse zu starten, und alles beginnt mit der Klasse Random, mit der Sie Zahlen ohne einen bestimmten Bereich generieren können, indem Sie ihre Instanz initialisieren und die Methode Next() aufrufen, um eine zufällige Ganzzahl zu erhalten und zu erhalten eine Dezimalzahl mit der Methode NextDouble().

Sie können eine Klasse von Grund auf neu schreiben. Sie können die Klasse Random, die Klasse Environment.TickCount oder die Klasse RNGCryptoServerProvider verwenden, um eine Zufallsklasse in C# zu erstellen.

Erstellen Sie eine Funktion zum Seeding einer zufälligen Klasse in C#

Erstellen Sie eine Funktion wie public static int random_func(int _min, int _max){} und erstellen Sie ein Objekt aus der Random-Klasse, um die Next()-Methode auf die min- und max-Werte anzuwenden.

Sie können diese Technik wiederholen, indem Sie eine statische Klasse erstellen, die die öffentliche Funktion enthält, die Operationen an einem privaten statischen Objekt aus der Klasse Random ausführt. Für eine echte zustandslose statische Methode können Sie sich strikt auf eine Guid verlassen, um Zufallszahlen mit etwas wie Guid.NewGuid().GetHashCode() zu generieren.

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);

      */
    }
  }
}

Ausgang:

Erstellen Sie eine Funktion zum Seeding einer zufälligen Klasse

Es ist wichtig zu verstehen, dass das Ziel von Guid darin besteht, einzigartig und nicht gleichmäßig verteilt zu sein und in den meisten Fällen das Gegenteil von Zufälligkeit sein kann und keine gleichmäßige Verteilung implementiert. Aus diesem Grund ist das Erstellen einer Funktion basierend auf der Klasse Random ein gültiger Ansatz . Sie erhalten auch eine bessere Zufälligkeit, indem Sie eine zufällige Klasse mit einer größeren unvorhersehbaren Zahl wie Random((int)DateTime.Now.Ticks) ausstatten.

Verwenden Sie die Klasse Random(), um eine zufällige Klasse in C# zu erstellen

Das Erstellen einer Instanz der Klasse Random und das Anwenden der Methode Next() auf diese Instanz in einer Schleife ist immer der beste Weg, um die Klassen in C# zu starten. Die Zahlen, die eine einzelne Random-Klasseninstanz generiert, sind immer gleichmäßig verteilt, und Sie können sie mit identischen Werten ausstatten, um identische Zufallszahlen zu erzeugen, indem Sie für jede Zufallszahl in schneller Folge eine neue Random-Klasseninstanz erstellen.

Es ist eine großartige Praxis, eine Random-Klasse der Vollständigkeit halber neu zu setzen und eine neue Instanz aus dem neuen Seed zu erstellen, und das erneute Seeding ist eine großartige Option, wenn die Vorhersagbarkeit zu einem Problem wird, und abgesehen von der Verwendung eines echten Zufallsgenerators, Sie sollten das Seeding schneller durchführen, als die Mustererkennung von einer Angreiferseite anwenden kann, und sicherstellen, dass keine zwei Generatoren mit den gleichen Werten geseedet werden.

Das new Random() wird immer mit der Systemuhr initialisiert, sodass Sie die gleichen Werte erhalten können. Daher sollten Sie eine einzelne Random-Instanz behalten und die Next()-Methode auf derselben Instanz verwenden.

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();
    }
  }
}

Ausgang:

Use the Random() Class to Seeding a Random Class

Am wichtigsten ist, dass Sie ein lock benötigen, um den Seed mit Next() zu synchronisieren, denn wenn Sie Next() gleichzeitig auf mehrere Threads anwenden, können Sie das Ergebnis noch zufälliger machen und können dies auch kann die interne Implementierung unterbrechen. Die Sperre garantiert Thread-Sicherheit, und die Synchronisierung ist der beste Ansatz, um maximale Zufälligkeit zu erreichen.

Die Verwendung von lock mit einer Random-Klasseninstanz ist eine Alternative, aber weniger Thread-sicher als die andere. Angenommen, Sie verwenden einen thread- und parameterlosen Konstruktor des Random-Objekts.

In diesem Fall kann es zu einer Verzögerung kommen, die durch den Aufruf der Methode Thread.Sleep verursacht wird, was dazu führt, dass ein anderer Seed-Wert für dieses Objekt erzeugt wird, und es kann eine andere Folge von Zufallszahlen generiert werden.

Verwenden Sie die Eigenschaft Environment.TickCount, um eine zufällige Klasse in C# zu erstellen

Es gehört zum Namensraum System und ist wichtig, um die Anzahl der Millisekunden seit dem Systemstart zu ermitteln, und stellt eine 32-Bit-Ganzzahl mit Vorzeichen dar. Diese Eigenschaft wechselt zwischen Int32.MinValue und Int32.MaxValue, die jeweils negative und positive Zahlen darstellen, und Sie können das Vorzeichenbit entfernen, um eine nicht negative Zahl zu erhalten, die alle 24.9 Tage zwischen Null und dem maximalen positiven Wert wechselt .

Die Auflösung der vorzeichenbehafteten 32-Bit-Ganzzahl ist auf die Auflösung Ihres Systemzeitgebers im Bereich von 10 bis 16 Millisekunden beschränkt. Am wichtigsten ist, dass die von System.Random verwendete Implementierung Environment.TickCount ist und das Umwandeln von DateTime.UtcNow.Ticks vermeidet und die Wiederverwendung des Seedings der zufälligen Klassen in Ihrer C#-Anwendung erleichtern kann.

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();
    }
  }
}

Ausgang:

Use the Environment.TickCount Property to Seeding a Random Class

Verwenden Sie die Klasse RNGCryptoServiceProvider, um eine zufällige Klasse in C# zu erstellen

In einigen Einzelfällen ist die Verwendung der Klasse RNGCryptoServerProver erforderlich. Es gehört zum Namensraum System.Security.Cryptography und implementiert einen kryptografischen RNG (Random Number Generator) unter Verwendung der vom CSP (Cryptographic Service Provider) bereitgestellten Implementierung und kann nicht vererbt werden.

Es ist wichtig, es entweder direkt oder indirekt zu entsorgen, da es die Schnittstelle IDisposable implementiert und Sie die Methode Dispose in einem try/catch-Block aufrufen können. In C# können Sie das Konstrukt using verwenden, um es zu beseitigen, um einen perfekten Seed für Ihre zufällige Klasse zu erstellen.

Die Klasse System.Security.Cryptography.RNGCryptoServiceProvider ist Thread-sicher und dient einem echten Bedarf, indem sie Werte aus einem bekannten Seed reproduziert. Es ist jedoch mathematisch unmöglich, eine Funktion zu erstellen, die zwei unabhängige Werte erzeugen kann, und dies impliziert auch, dass jedes kryptografische Schema nicht vollständig sicher ist, und manchmal können die bloßen Kosten seiner Verwendung zu hoch sein.

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);
    }
  }
}

Ausgang:

Use the RNGCryptoServiceProvider Class to Seeding a Random Class

Sie können die Methoden Next(int) oder Next(int min, int max) verwenden, um Zufallszahlen im Bereich zu generieren, oder Sie können die Methoden Next() und NextBytes() verwenden, um jeweils zufällige Ganzzahlen und Serien zu generieren von Bytewerten. Entweder stellen Sie einen Startwert über die Konstruktorüberladung bereit, oder das Framework erledigt dies für Sie.

Es ist ein teurer Ansatz, die Klasse Random zu instanziieren, und eine Übertreibung kann die Leistung Ihrer C#-Anwendungen verringern; Instanziieren Sie stattdessen eine einzelne Random-Instanz und rufen Sie die Next()-Methode mehrmals auf. Kryptografie ist ein sichererer und schützenderer Ansatz, um eine zufällige Klasse in C# zu initiieren.

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

Verwandter Artikel - Csharp Math