Zufallsoperationen in C#
Lernen Sie die Random-Klasse in C#, um Zufallszahlen und -werte mit Next, NextDouble und praktischen Beispielen zu erzeugen.
In C# ist die Hauptklasse zum Erzeugen von Zufallswerten System.Random.
Sie wird häufig in Szenarien wie Spielmechaniken, Simulationen oder beim Erstellen von Testdaten verwendet.
In diesem Artikel sehen wir uns die Zahlenerzeugung mit Random, Bereichsdefinitionen, das Mischen von Arrays,
die Verwendung von Seeds und die Vorgehensweise bei kryptographisch sicheren Zufallszahlen an.
Grundlegende Verwendung: Next()
Next() erzeugt eine nicht-negative int-Zahl. Überladene Versionen erlauben die Angabe von Bereichen.
var rnd = new Random();
int a = rnd.Next(); // 0..Int32.MaxValue
int b = rnd.Next(10); // 0..9 (obere Grenze exklusiv)
int c = rnd.Next(5, 11); // 5..10 (untere inkl., obere exklusiv)
Console.WriteLine($"{a}, {b}, {c}");
Gleitkommazahlen: NextDouble()
NextDouble() erzeugt eine Zahl zwischen 0.0 und 1.0 (exklusiv). Der Bereich kann skaliert werden.
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}");
Byte-Array füllen: NextBytes()
Wenn zufällige Bytes benötigt werden (z. B. Dummy-Daten), verwenden Sie NextBytes.
var rnd = new Random();
byte[] buffer = new byte[8];
rnd.NextBytes(buffer);
Console.WriteLine(BitConverter.ToString(buffer)); // Beispiel: "3F-91-0C-..."
Reproduzierbarkeit mit Seed
Ein Random, das mit demselben Seed initialisiert wurde, erzeugt dieselbe Zahlenfolge. Nützlich für Tests.
var r1 = new Random(12345);
var r2 = new Random(12345);
Console.WriteLine(r1.Next() == r2.Next()); // True
Häufiger Fehler: Mehrfaches Erstellen von Random
Wird new Random() in kurzer Zeit mehrfach erstellt, können ähnliche/gleiche Ergebnisse entstehen (zeitbasierter Seed).
Lösung: Eine einzelne Instanz während der gesamten Anwendung verwenden oder Random.Shared nutzen.
// SCHLECHT
int SchlechteErzeugung()
{
return new Random().Next(100); // neue Instanz bei jedem Aufruf
}
// GUT
var rnd = new Random(); // gemeinsam nutzen
int GuteErzeugung() => rnd.Next(100);
// .NET 6+: Random.Shared (thread-sicher)
int BessereErzeugung() => Random.Shared.Next(100);
Beispiele: Farbe, Student, Code-Erzeugung
var rnd = Random.Shared;
// Zufällige Farbauswahl
string[] farben = { "Rot", "Blau", "Grün", "Gelb", "Lila" };
string gewaehlteFarbe = farben[rnd.Next(farben.Length)];
Console.WriteLine("Gewählte Farbe: " + gewaehlteFarbe);
// Zufällige Studentenauswahl
string[] studenten = { "Anna", "Markus", "Julia", "David", "Sophia" };
string gewaehlterStudent = studenten[rnd.Next(studenten.Length)];
Console.WriteLine("Gewählter Student: " + gewaehlterStudent);
// Zufälliger Code (6 Zeichen)
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("Verifizierungscode: " + sb.ToString());
Array-Mischen (Fisher–Yates)
Um Elemente mit gleicher Wahrscheinlichkeit zu mischen, wird der Fisher–Yates-Algorithmus verwendet.
var rnd = Random.Shared;
int[] array = { 1, 2, 3, 4, 5 };
for (int i = array.Length - 1; i > 0; i--)
{
int j = rnd.Next(0, i + 1); // 0..i
(array[i], array[j]) = (array[j], array[i]);
}
Console.WriteLine(string.Join(", ", array));
Zufällige Auswahl
Zufälliges Auswählen eines Elements aus einer Sammlung:
var rnd = Random.Shared;
string[] farben = { "Rot", "Blau", "Grün", "Gelb" };
string auswahl = farben[rnd.Next(farben.Length)];
Console.WriteLine("Auswahl: " + auswahl);
Einfaches zufälliges Passwort (Demo)
Nicht kryptographisch sicher; geeignet für Spiele/Testdaten. Für Sicherheit siehe unten.
var rnd = Random.Shared;
const string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
int laenge = 10;
var sb = new System.Text.StringBuilder(laenge);
for (int i = 0; i < laenge; i++)
{
int idx = rnd.Next(alphabet.Length);
sb.Append(alphabet[idx]);
}
Console.WriteLine("Passwort (Demo): " + sb.ToString());
Kryptographisch sichere Zufallszahlen
Für sicherheitskritische Szenarien wie Passwort-, Token- oder Schlüsselgenerierung
sollte Random nicht verwendet werden.
Stattdessen System.Security.Cryptography.RandomNumberGenerator oder die RandomNumber-Hilfsmethoden verwenden.
using System.Security.Cryptography;
// 0..int.MaxValue (exklusiv)
int n1 = RandomNumberGenerator.GetInt32(int.MaxValue);
// Bestimmter Bereich
int n2 = RandomNumberGenerator.GetInt32(100, 201); // 100..200
// Zufällige Bytes
byte[] key = new byte[32];
RandomNumberGenerator.Fill(key);
Console.WriteLine($"{n1}, {n2}, {BitConverter.ToString(key)}");
Hinweis zur Verteilung
Random erzeugt Werte, die einer gleichmäßigen (uniformen) Verteilung nahekommen.
Für Verteilungen wie Normal (Gauß) sind Transformationen (z. B. Box–Muller) oder Statistik-Bibliotheken erforderlich.
TL;DR
Random.Next,NextDouble,NextBytes→ grundlegende APIs.- Eine einzelne Instanz oder
Random.Sharedverwenden; kein mehrfachesnew Random(). - Gleicher Seed → gleiche Zahlenfolge (reproduzierbare Tests).
- Für Array-Mischen den Fisher–Yates-Algorithmus anwenden.
- Für Sicherheit
RandomNumberGenerator/GetInt32nutzen.