Seed eine zufällige Klasse in C#
-
Erstellen Sie eine Funktion zum Seeding einer zufälligen Klasse in
C#
-
Verwenden Sie die Klasse
Random()
, um eine zufällige Klasse inC#
zu erstellen -
Verwenden Sie die Eigenschaft
Environment.TickCount
, um eine zufällige Klasse inC#
zu erstellen -
Verwenden Sie die Klasse
RNGCryptoServiceProvider
, um eine zufällige Klasse inC#
zu erstellen
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:
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:
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:
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:
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.
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