C# Random İşlemleri
C#’ta Random sınıfını kullanarak rastgele sayı, değer ve seçim üretmeyi öğrenin. Next, NextDouble ve örneklerle anlatım.
C#’ta rastgele değer üretmek için temel sınıf System.Random’dır.
Oyun mekaniği, simulasyon, test verisi oluşturma gibi senaryolarda sıkça kullanılır.
Bu yazıda Random ile sayı üretme, aralık belirleme, dizileri karıştırma, tohum (seed) kullanma
ve kriptografik olarak güçlü rastgelelik ihtiyaçlarında ne yapılması gerektiğini göreceğiz.
Temel Kullanım: Next()
Next() sıfır veya pozitif bir int üretir. Aralık için aşırı yüklenmiş sürümler kullanılır.
var rnd = new Random();
int a = rnd.Next(); // 0..Int32.MaxValue
int b = rnd.Next(10); // 0..9 (üst sınır hariç)
int c = rnd.Next(5, 11); // 5..10 (alt dahil, üst hariç)
Console.WriteLine($"{a}, {b}, {c}");
Ondalıklı Değer: NextDouble()
NextDouble() 0.0 ile 1.0 arasında (1.0 hariç) bir sayı üretir. Aralığı ölçekleyebilirsiniz.
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}");
Bayt Dizisi Doldurma: NextBytes()
Rastgele baytlar gerekir (ör. dummy veri) ise NextBytes kullanılır.
var rnd = new Random();
byte[] buffer = new byte[8];
rnd.NextBytes(buffer);
Console.WriteLine(BitConverter.ToString(buffer)); // Örn: "3F-91-0C-...”
Tohum (Seed) ile Tekrarlanabilirlik
Aynı seed ile kurulan Random aynı sayı dizisini üretir. Testler için faydalıdır.
var r1 = new Random(12345);
var r2 = new Random(12345);
Console.WriteLine(r1.Next() == r2.Next()); // True
Yaygın Hata: Arka arkaya Random Oluşturmak
Kısa sürede peş peşe new Random() oluşturmak benzer/aynı sonuçlar üretebilir (zaman tabanlı seed).
Çözüm: Uygulama boyunca tek örnek kullanın veya Random.Shared tercih edin.
// KÖTÜ
int KotuUretim()
{
return new Random().Next(100); // her çağrıda yeni örnek
}
// İYİ
var rnd = new Random(); // paylaş
int IyiUretim() => rnd.Next(100);
// .NET 6+: Random.Shared (thread-safe)
int DahaIyiUretim() => Random.Shared.Next(100);
Örnekler: Renk, Öğrenci, Kod Üretimi
var rnd = Random.Shared;
// Rastgele renk seçimi
string[] renkler = { "Kırmızı", "Mavi", "Yeşil", "Sarı", "Mor" };
string secilenRenk = renkler[rnd.Next(renkler.Length)];
Console.WriteLine("Seçilen renk: " + secilenRenk);
// Öğrenci listesinden rastgele seçim
string[] ogrenciler = { "Ayşe", "Mehmet", "Elif", "Deniz", "Burak" };
string secilenOgrenci = ogrenciler[rnd.Next(ogrenciler.Length)];
Console.WriteLine("Seçilen öğrenci: " + secilenOgrenci);
// Rastgele kod üretimi (6 karakter)
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("Doğrulama kodu: " + sb.ToString());
Diziyi Karıştırma (Fisher–Yates)
Elemanların sırasını eşit olasılıkla karıştırmak için Fisher–Yates önerilir.
var rnd = Random.Shared;
int[] dizi = { 1, 2, 3, 4, 5 };
for (int i = dizi.Length - 1; i > 0; i--)
{
int j = rnd.Next(0, i + 1); // 0..i
(dizi[i], dizi[j]) = (dizi[j], dizi[i]);
}
Console.WriteLine(string.Join(", ", dizi));
Rastgele Seçim (Random Pick)
Bir koleksiyondan rastgele öğe seçmek:
var rnd = Random.Shared;
string[] renkler = { "Kırmızı", "Mavi", "Yeşil", "Sarı" };
string secim = renkler[rnd.Next(renkler.Length)];
Console.WriteLine("Seçim: " + secim);
Basit Rastgele Şifre (Demo)
Kriptografik değildir; oyun/test verisi için uygundur. Güvenlik için aşağıdaki bölümdeki yöntemi kullanın.
var rnd = Random.Shared;
const string alfabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
int uzunluk = 10;
var sb = new System.Text.StringBuilder(uzunluk);
for (int i = 0; i < uzunluk; i++)
{
int idx = rnd.Next(alfabet.Length);
sb.Append(alfabet[idx]);
}
Console.WriteLine("Şifre (demo): " + sb.ToString());
Kriptografik Olarak Güçlü Rastgelelik
Parola, token, anahtar üretimi gibi güvenlik kritik senaryolarda Random kullanmayın.
Bunun yerine System.Security.Cryptography.RandomNumberGenerator veya RandomNumber yardımcılarını kullanın.
using System.Security.Cryptography;
// 0..int.MaxValue (dahil değil) arası
int s1 = RandomNumberGenerator.GetInt32(int.MaxValue);
// Belirli aralık
int s2 = RandomNumberGenerator.GetInt32(100, 201); // 100..200
// Rastgele baytlar
byte[] key = new byte[32];
RandomNumberGenerator.Fill(key);
Console.WriteLine($"{s1}, {s2}, {BitConverter.ToString(key)}");
Dağılım Hakkında Not
Random düzgün (uniform) dağılıma yakın değerler üretir.
Normal (Gauss) gibi dağılımlar için dönüşüm (örn. Box–Muller) veya istatistik kütüphaneleri gerekir.
TL;DR
Random.Next,NextDouble,NextBytes→ temel API’ler.- Tek örnek kullanın ya da
Random.Shared; peş peşenew Random()oluşturmayın. - Aynı seed → aynı sayı dizisi (tekrarlanabilir testler).
- Dizi karıştırma için Fisher–Yates uygulayın.
- Güvenlik için
RandomNumberGenerator/GetInt32kullanın.