Wird geladen...

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.Shared verwenden; kein mehrfaches new Random().
  • Gleicher Seed → gleiche Zahlenfolge (reproduzierbare Tests).
  • Für Array-Mischen den Fisher–Yates-Algorithmus anwenden.
  • Für Sicherheit RandomNumberGenerator / GetInt32 nutzen.