Bilgisayarlar nasıl rastgele sayı üretebilir?
Bilgisayarlar, aritmetik işlemleri bir insandan çok daha hızlı şekilde hesaplayabilmesi amacıyla tasarlanmıştır. Bilinen ilk bilgisayar milattan önce Çin’de, bizim “abaküs” olarak bildiğimiz basit bir makine olarak icad edilmişti. Gün geçtikçe daha gelişmiş makinelere ihtiyaç duyuldu. Mekanik hesap makinesi denilen, içerisinde çarklar dolu bir makine kullanılmaya başlandı. The Imitation Game filminde anlatılan bilgisayarın ortaya çıkış hikayesinde olduğu gibi, zamanın mevcut imkanlarıyla yapılan hesaplamaların da artık yetersiz kalmasıyla yeni çözümler aranmaya başlandı. İşte modern bilgisayarlar bundan sonra ortaya çıktı. Hiç düşündünüz mü tek işi kendisine verilen komutları hesaplamak olan bu makineler, nasıl olur da rastgele sayılar üretebilir?
Sabit verilerle rastgele sayı üretmek mümkün değildir. Bilgisayarlar zar atmaz, sadece yapılması gereken işlemi yapar ve hesapladığı sonucu verir. 2+2 her zaman 4 eder. Bazen 5 sonucunu verdiğini gördünüz mü?
Bilgisayarlar rastgele sayı üretebilmek için, rastgele veri almak zorundadır. Bu veriler ise çevresel faktörlerle elde edilir. Yani gereken tek şey sabit olmayan, değişken ve rastgele bir durumun yaşanmış olmasıdır.
Rastgele veri almanın birçok yöntemi vardır. Bilgisayar kullanıcısının klavye üzerindeki tuşlara basma hızları, mouse hareketleri gibi gerçek “rastgele veriler” elde edilebilir. Bu yöntemde bilgisayara gelen, fiziksel eylemler sonucu oluşturulan veriler kullanılır. Fakat fiziksel eylemlerle elde edilen bu verilere 100% güvenilir diyemeyiz. Bu bilgisayarın aynı hareketleri yapmaya programlı bir robot tarafından kontrol ediliyor olma ihtimali gibi.. Bu yüzden bu yöntem ile daha güvenilir sonuçlar almak için öngörülebilir olmayan verilerin kullanıldığından emin olunmalı.
Başka bir yöntem olan PRNG (pseudorandom number generator) ise, seed isimli, sağlanan temel verilerle oluşturulan rastgele sayılardır. PRNG yönteminde rastgele sayılar üretebilmek için bir algoritma kullanılır. PRNG’nin ihtiyaç duyduğu seed‘ler kendisine sağlandıktan sonra geri kalan tüm işlemler bu algoritmayla tamamlanır. Sağlanan seed ne kadar güvenilir ise, oluşturulan değer de o kadar güvenilir sonuç verir.
İşte bu yönteme örnek, basit bir C programı:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
int i, num;
srand(time(0)); // Seed verisi sağla (örn: şimdiki zaman)
for(i=0; i<5; ++i) {
num = rand(); // Bununla rastgele sayı oluştur
printf("%d\n", num);
}
return 0;
}
Eğer seed verisini sabit bir değer yapsaydık programı çalıştırdığımız her seferde aynı çıktılar üretilirdi. Yukarıdaki örnekte seed verisi, time(0)
fonksiyonu kullanılarak mevcut zamanın saniyelik değeriyle sağlanıyor. Böylece her saniye farklı değerler ile besleme yapabiliyoruz.
$> gcc rand.c -o rand && ./rand
967057489
1178977127
236962620
1196072802
1948647294
Fakat bu programı saniyede bir defa değil de, 10 defa çalıştırsaydık, çalıştırılan her bir programın çıktısı yine aynı değerleri verecekti.
for i in $(seq 10); do ./rand; done
Örnekteki programı 10 defa çalıştırdık ve birbirini yineleyen çıktılar elde ettik.
Bu yüzden seed verileri daha güvenilir yollarla sağlanmalı. Mesela bu veriler arasına CPU’nun clock hızını veya zamanın saniyelik değil de mikrosaniyelik değerini de ekleyebilirsiniz.
Rastgele sayılar ayrıca UNIX platformlarında /dev/random
veya /dev/urandom
isimli sanal dosyalar tarafından da bizlere sağlanabilir. Her ikisi de pseudorandom sayılar üretir, seed değerleri aynı yerden gelir fakat aralarında başka farklılıklar bulunur. Bu farklar Thomas Hühn tarafından yazılmış Myths about /dev/urandom makalesinde detaylı ve şemalı olarak anlatılmış.