Rastgele kavramı bir çok bilimin ilgi alanına giren derin bir konudur. Burada tutup da bu kavramı tüm yönleri ile ele alarak incelemeye çalışmayacağım. Rastgele kavramını, bir yazılımcının bilmesi gerektiği kadar ve şekilde anlatmaya çalışacağım. Bunun yanında yazılım geliştirme sürecinde rastgele sayılar elde ederken hangi durumlarda hangi yolların nasıl kullanılması gerektiğini anlatmaya çalışacağım. Haydi rastgele.
Bu makalede anlatılan rastgele işlemler ile ilgili daha detaylı örnekler için "Rastgele Metin(Üye Kodu, Şifre vb) Üretmek" adlı makalemi okumanızı tavsiye ederim.
Rastgele Kavramının Anlaşılması
Rastgelelikten bahsedebilmek için belirli şartların sağlanması gerekmektedir. Arkadaşımızdan rastgele 10 tane sayı söylemesi ni istediğimizde 10 sayının tamamı ya da büyük bir kısmı birbiri ile aynı ise rastgelelikten bahsedemeyiz. Çünkü istatistiksel olarak rastgele sayıların birbirini tekrarlama oranının çok düşük olması gerekmektedir. Tabi şunu da unutmamak lazım ki rastgele elde edilecek 10 sayı 1 ile 5 arasında olacak olursa ister istemez tekrarlayan sayılar olacaktır. Sayılar birbirini tekrarlasa da düzgün bir dağılım gösteriyorsa yani bazı sayılar diğerlerine nazaran daha fazla tekrarlamıyorsa yine rastgelelikten söz edebiliriz. Özetlemek gerekirse rastgele sayılar ait oldukarı küme içerisinde istatistiksel olarak düzgün(eşit sayılabilecek) bir dağılım göstermelidir.
Eşit dağılım şartının yanında sayıların kestirilemez olması da önemli diğer bir şarttır. Arkadaşımız 1,3,5,7,... şeklinde sayılar söylerse bunların da rastgele olmadığını söyleyebiliriz. Ancak kestirilemezlik şartı az önceki örnekte bahsedilenden daha geniş bir kavramdır. Sayılar kendi aralarında belirli bir kurala bağlı olmasa yani bu şekilde kestirilemez olsa bile zaman, ruh hali, hava koşulları vb değişkenlere göre de kestirilemez olmalıdır. Örneğin arkadaşımız hava kapalıyken hep belirli bir aralıktan sayılar söylüyorsa ya da sevinçli iken hep çift sayılar söylüyorsa rastgelelik sağlanmaz.
Yukarıda kendimce belirlediğim şartlarla rastgelelik kavramını belki de doğru olmayan bir şekilde, ancak bir yazlımcı olarak, kavramın değişik boyutlarını anlamamızı sağlayacak bir şekilde açıklamaya çalıştım. Dikkat ettiyseniz bahsettiğim şartlar birbirlerine çok yakın kavramlar ve belki de aynı şeyleri ifade ediyorlar. Yani eşit dağılım koşulu sağlanmıyorsa bu aynı zamanda sayıların kestirilebilir olduğu anlamına da gelebilir.
İnsanın anlayabileceği şekilde, rastgeleliği, değerini tahmin ederken hiç bir şekilde akıl yürütemediğimiz şey olarak düşünebiliriz.
Bilgisayar Ortamında Rastgelelik
Kavramsal incelemeden sonra şimdi de rastgeleliği bilgisayar dünyasında incelemeye çalışalım. Makinelerin dünyasında rastgele diye bir şey olmadığı için rastgele sayı üretimi değişik algoritmalarla bir önceki bölümde anlatmaya çalıştığım şartlara tam olarak olmasa da kabul edilebilir bir derecede uyan sayılar üretilmesi ile simule edilmiş/yerine getirilmiş olur. Bu şartlar eşit dağılım ve kestirilemezlikti.
.Net Ortamında Rastgele İşlemler
.Net, değişik rastgele ihtiyaçlarımız için temel teşkil edecek hazır bazı sınıf ve metodlar barındırır. Mimarinin alt kısımlarında yer alanları bir kenara bırakırsak, en sıklıkla kullanacağımız nesneler olan VbMath, Random ve RNGCryptoServiceProvider sınıflarını inceleyelim.
VbMath Sınıfı
VbMath, Microsoft.VisualBasic isim alanının(namespace) altında bulunan bir sınıftır. Bu sınıf, rastgele işlemlerde kullanabileceğimiz statik (vb’ deki shared) olan
• Randomize()
• Randomize(Double)
• Rnd() as Single
• Rnd(Single) as Single
şeklinde tanımlanan 2’ şer overloadları olan Rnd ve Randomize metod ve fonksiyonlarını içerir. Bu sınıf VisualBasic’ in eski sürümlerinden beri mevcuttur. Şimdi bu sınıfta yer alan metod ve fonksiyonları inceleyelim.
Rnd[(Number)]
Bu fonksiyon çok sıklıkla kullanılır ve neredeyse yapılabilecek tüm rastgele işlemlerin temelini oluşturur. Fonksiyon, 1’ den küçük, 0’ a eşit yada 0’ dan büyük single tipinde bir değer döndürür.
Nasıl Çalışır
Rnd fonksiyonu, kendi içerisinde tuttuğu tohum(seed) sayısını belirli bir algoritmaya göre işler ve sonucu geri döner. Algoritma sabit olduğu için aynı tohum hep aynı sonucu verir. Fonksiyonun kullacağı tohum sayısı, fonksiyonu –(eksi) değerli bir parametreyle çağırmakla ya da Randomize() metodunu kullanmakla belirlenir. Rnd fonksiyon statik (vb’ deki shared) bir fonksiyondur. Yani uygulama bazında tek bir örneği vardır. Uygulama çalışmaya başlayıp da fonksiyon ilk yüklendiğinde tohum değeri 327680’ dir. Fonksiyon her bir çalışmasında, tohum sayısını belirli bir algoritmayla işleyerek bir sayı üretir. Tohum değeri yeni üretilen bu sayı olarak atanırken fonksiyon bu yeni tohumu belirli bir sayıya bölerek 0 ile 1 arasında olmasını sağlar ve geri döner.
Rnd’ nin sayı üretiminde kullandığı algoritma aldığı tohuma göre kestirilebilir bir sayı üretir. Yani aynı tohumla aynı sayı üretilir. Ancak algoritmanın yapısından ötürü elde edilen sayı 0 ile 1 arasında istatistiksel olarak düzgün bir dağılm gösterdiği ve tohum değerinin değiştirilebilir olmasından ötürü yazının başında bahsettiğimiz şartlara uyan rastgele sayılar ürettiğini kabul edebiliriz.
Yukarıda anlatılanlardan çıkarabileceğimiz önemli bir diğer nokta da Rnd fonksiyonunun tohum değeri elle değiştirilene kadar belirli bir seriyi takip etmesidir. Yani ister –(eksi)değerli parametre ile ister ileride anlatılacak olan Random fonksiyonu ile biz vermiş olalım isterse de kendi tohum değerini kullanıyor olsun Rnd her çalışmasında tohum değerinden yeni bir sayı üretip bunu tohum değeri olarak aldığı için ilk tohuma ait serileri takip etmiş olur. Bu “seri “ kavramı konu ile ilgili pek makale ve örnekte geçse de ne olduğu anlatılmadığı için çoğu kişinin kafasını karıştırır.
Dikkat etmek gerekir ki belirli bir serinin takip edilmesi, rastgeleliğin güvenlik işlemlerinde kullanılacağı durumlar için sakıncalıdır. Zira fonksiyonun kullandığı algoritmayı bilen birisi fonksiyonun hangi seriyi takip ettiğini bulup serinin sonraki elemanlarını bilebilir. Bu handikaptan ancak, fonksiyonun kullacağı tohum değerine sık sık kestirilemez yeni değerler vererek kurtulabiliriz. Rastgele sayı üretebilmek için yine rastgele sayıya(tohum) ihtiyacım var böyle şey olmaz diye düşünmeyin. Çünkü baştan da dediğim gibi yapmaya çalıştığımız şey rastgeleliğe ulaşmak değil onu simule etmek yani belirli bir kalitede rastgeleliğin kurallarına uymak. Fonksiyon yüksek güvenliğin söz konusu olduğu durumlar haricinde ihtiyacımıza cevap veriyor, bu özel durumlarda ne yapacağımıza ise yazının ilerleyen bölümlerinde cevap vereceğim.
Rnd fonksiyonunun nasıl çalıştığını anladıktan sonra teknik detaylarına geçebiliriz. Rnd() fonksiyonu opsiyonel olarak single tipinde Number parametresini alır. Bu parametre rastgele sayının nasıl üretileceğini belirler. Şöyle ki;
Number; 0’ dan küçükse, değer tohum(seed) olarak atanır ve bu tohumdan bir sayı üretilir.
Number; 0’ dan büyükse, serideki bir sonraki sayıyı döner, yani mevcut tohumdan yeni bir tohum-sayı üretilir.
Number; 0’ a eşitse, yeni bir sayı üretilmez ve fonksiyon son üretilen sayıyı döner.
Number; parametresi verilmemişse, serideki bir sonraki sayıyı döner.
Örnek 1: Rnd()’ nin Kullanım Örnekleri
| Metod 1: |
Metod 2: |
For i As Integer = 1 To 3
Write(Rnd(-1))
Write(Rnd())
Next
For i As Integer = 1 To 3
Write(Rnd(-1))
Write(Rnd())
Next
|
Write(Rnd(-1))
For i As Integer = 1 To 3
Write(Rnd())
Next
Write(Rnd(-1))
For i As Integer = 1 To 3
Write(Rnd())
Next
|
Yukarıdaki kod ile aşağıdaki sonuçları elde ederiz.
0,2240070104598999
0,0358458161354065
0,2240070104598999
0,0358458161354065
0,2240070104598999
0,0358458161354065
0,2240070104598999
0,0358458161354065
0,2240070104598999
0,0358458161354065
0,2240070104598999
0,0358458161354065
|
Yukarıdaki kod ile aşağıdaki sonuçları elde ederiz.
0,2240070104598999
0,03584581613540650
0,08635234832763670
0,16426390409469600
0,17973577976226800
0,57320052385330200
0,2240070104598999
0,03584581613540650
0,08635234832763670
0,16426390409469600
0,17973577976226800
0,57320052385330200
|
Görüldüğü üzere Rnd(-1) dediğimizde; tohuma, -1 değilse de -1 den elde edilen bir değer atanıyor ve fonskiyon hep aynı sayıyı geri dönüyor.
Rnd() şeklinde çağırıldığında ise serinin bir sonraki elemanını geri dönüyor.
Ancak tekrar Rnd(-1) denildiğinde tohum tekrar ilk değer ile atanmış olduğu için fonksiyon seriyi takip etmeyi bırakıp aynı seriye baştan başlıyor.
|
Görüldüğü üzere –(eksi) bir değer verilerek tohumu belirlediğimizde tohum yeniden belirlenene kadar Rnd() fonksiyonu yeni sayılar üretiyor.
İkinci kısımda aynı sayıların elde edilmesi ile Rnd() fonksiyonunun aynı tohum için aynı seriyi takip ettiğini görmemizi sağlıyor.
|
Randomize[(Number)]
Randomize metodu Rnd fonksiyonuna yardımcı olarak hazırlanmıştır. Amacı ise Rnd’ nin kullanacağı tohum değerini değiştirmektir. Opsiyonel olarak double tipinde Number parametresini alır. Metod verildiyse bu parametreyi verilmediyse sistem saatinden elde edeceği bir değeri kullanarak Rnd() fonksiyonunun kullandığı tohum sayısını değiştirir. Rnd() fonksiyonuna –(eksi) değerli bir parametre vererek zaten tohumu değiştirebiliyorduk, buna ne gerek sorusunun cevabını iyice anlayabilmek için metodun nasıl çalıştığını incelemek gerekir.
Randomize’ ın Parametresiz Kullanımı
Randomize metodu parametre vermeden de çağırılabilir. Bu durumda metodun sistem saatinden elde ettiği bir değeri kullanıdığından bahsetmiştik. Ancak Randomize() sistem saatinden elde ettiği bu değeri direkt tohum olarak kullanmak yerine mevcut tohum değerini bu değer ile işleyerek bambaşka yeni bir tohum elde eder. Bu sayede tohum değeri sistem saati ile paralel olarak ama mevcut tohuma göre farklı bir şekilde değişeceği için, Rnd fonksiyonu değişik zamanlarda değişik tohum değerleri alarak değişik serileri takip edecek ve neticede kestirilemez rastgele sayılar üretebilecektir. Bu bilgiyi buraya kadar anlatılanlarla birleştirsek fena olmaz, çünkü rastgeleliğin kullanım amacı ve şekli dikkate alınmadığında Randomize’ ın parametre verilmeden kullanılması rastgele işlemlerde en sık karşılaşılan hatalardan birisine sebep olur. Şöyle ki; bildiğinizi gibi aslında Rnd fonksiyonu rastgele sayı üretimi için kendi başına yeterli. Ard arda ürettiği sayılar rastgele sayılabilecek bir yapıdadır. Fonksiyonun her yüklenişte aynı tohum ile başlaması handikapından dolayı tohum değerini değiştirmemiz gerektiğini de söylemiştik. İşte bu yüzden Randomize() diyerek tohuma rastgele sayılabilecek bir değer atadıktan sonra Rnd zaten rastgele sayılar üreteceği için ard arda 100 sayı üreteceğimiz bir durumda Rnd’ yi her çağırmamızdan önce Randomize’ ın da çalıştırılmasına gerek yoktur.
Randomize’ ın Parametreli Kullanımı
Metodun parametresiz kullanımı gerekli olabilecek faydalı bir yoldur. Farklı amaçlara hizmet ettikleri için kıyaslamak doğru olmasa da metodun parametreli kullanımı bence çok daha ilginç ve kullanımında dikkat edilmesi gereklidir.
Randomize metodu parametre vererek kullanıldığında çok değişik bir yeteneğe sahip olur. Bu yeteneğin ne olduğunu söylemeden önce nasıl ortaya çıktığından bahsedeyim. Randomize, aynı sistem saatini kullanırkende olduğu gibi parametre verildiğinde de verilen parametre direkt tohum olarak kullanılmaz. Daha ziyade; parametre, mevcut tohum ile bir işleme sokularak yeni bir tohum elde edilmesinde kullanılır. Yani Randomize’ a verdiğimiz sayıya yardımcı tohum diyebiliriz. Bu nedenle Randomize hep aynı sayı ile çağırılsa da Rnd’ den elde edeceğimiz değer değişecektir. Çünkü parametre aynı olsa da tohum her seferinde değişecektir. Rnd fonksiyonuna –(eksi) değerli bir parametre vererek tohumu belirledikten sonra yine belirli bir sayı ile Randomize çağırıldığında, hem ilk tohum hem de yardımcı tohum aynı olacağı için bu kombinasyon ne zaman ve nerede çalıştırılırsa çalışsın hep aynı seriye başlar. Bu sayede hep aynı seri takip edilmiş olur.
Metodun nasıl çalıştığını inceledikten sonra gelelim bahsettiğim yeteneğe. Randomize metodu kabaca belirtmek gerekirse belirli bir serinin neresinde kaldığını hatırlar. Örneğin Randomize(n) çağırıldıktan sonra tohum değeri Rnd(), Randomize() ya da Randomize(m) gibi başka bir şekilde tekrar değiştirilmiş olsa bile Randomize(n)tekrar çağırıldığında, n parametresine ait serinin neresinde kaldığını hatırlar. Olayın anlaşılması için “hatırlar” dediysem de aslında buna hatırlamak denemez. Daha ziyade Rnd ve Randomize’ ın kullandığı özel algoritmalar sayesinde bu sonuca varılmış olur. Bu karışık bir konu olduğu için örnek vererek anlatmaya çalışacağım.
Örnek 2: Rnd()’ nin Randomize İle Kullanılması
| Metod 3: |
Metod 4: |
Metod 5: |
AddToCollection(Rnd(-1))
For i As Integer = 1 To 18
Randomize(2)
AddToCollection(Rnd())
Next
ShowNumbers(3)
|
AddToCollection(Rnd(-1))
For i As Integer = 1 To 18
Randomize(5)
AddToCollection(Rnd())
Next
ShowNumbers(4)
|
AddToCollection(Rnd(-1))
Randomize(2)
For i As Integer = 1 To 3
AddToCollection(Rnd())
Next
Randomize(2)
For i As Integer = 1 To 3
AddToCollection(Rnd())
Next
Randomize(5)
For i As Integer = 1 To 3
AddToCollection(Rnd())
Next
Randomize(5)
For i As Integer = 1 To 3
AddToCollection(Rnd())
Next
Randomize(2)
For i As Integer = 1 To 3
AddToCollection(Rnd())
Next
Randomize(5)
For i As Integer = 1 To 3
AddToCollection(Rnd())
Next
ShowNumbers(5)
|
Elde edilen değerler:
0,2240070104599
0,582842886447906
0,490756034851074
0,501437366008759
0,469393372535706
0,565525352954865
0,277129411697388
0,407896459102631
0,546753764152527
0,864602625370026
0,379897594451904
0,365171134471893
0,674929738044739
0,48007470369339
0,533481359481812
0,373261392116547
0,853921294212341
0,411941587924957
0,00345993041992188
|
Elde edilen değerler:
0,2240070104599
0,894427359104156
0,802340507507324
0,813021838665009
0,780977845191956
0,877109825611115
0,588713884353638
0,719480931758881
0,858338236808777
0,176187098026276
0,691482067108154
0,676755607128143
0,986514210700989
0,79165917634964
0,845065832138062
0,684845864772797
0,165505766868591
0,723526060581207
0,315044403076172
|
Elde edilen değerler:
0,2240070104599
0,582842886447906
0,570361137390137
0,337237536907196
0,469393372535706
0,0636027455329895
0,961333513259888
0,719480931758881
0,622727274894714
0,168298304080963
0,691482067108154
0,103269279003143
0,599536061286926
0,48007470369339
0,937015295028687
0,812226235866547
0,165505766868591
0,634201109409332
0,0227317810058594
|
Görüldüğü üzere her sayıdan önce Randomize(2) çağırılmış olsa da Rnd() fonksiyonundan aynı değer dönmüyor.
Ancak burada gördüğümüz sayılar bir seriyi oluşturmuyor. Çünkü Rnd yi çağırmadan önce her seferinde Randomize(2) yi çağırarak tohumun değişmesine sebep oluyoruz. Yani üretilen sayı tohum olarak kullanılmıyor, tohum her sefer de yeniden belirleniyor.
|
Bu metodun Metod3’ ten tek farkı Randomize’ a verilen parametre değeri.
Görüldüğü üzere ilk tohum aynı olsa da Randomize’ a verilen parametre ile farklı değerler elde ediliyor.
|
Bu metodun, Metod 3 ve Metod4 ile beraber incelenmesi gerekiyor.
Açıklamaya gerek yok zannedersem. Randomize(2) ve Randomize(5) değişik sıralar ile çağırılsalar da sadece kendi başlarına çağırılmışçasına kaldıkları yerden devam ediyorlar.
Bu olayın açıklamasını yapmak ise programcılıktan çok matematik bilgisi ile olacak bir iş. Bu sebeple bunu açıklayamayacağım sadece metodların kullandığı algoritmaların özelliğinden kaynaklandığını söylemek ile yetineceğim.
|
Belirli Aralıklarda Rastgele Sayılar Üretmek
Malum Rnd fonksiyonu 0-1 arasında ondalık sayılar üretiyor. Maalesef gerçek hayatta daha farklı aralıklarda sayılara ihtiyacımız olur genellikle de 1 ile 1’ den büyük bir sayı arasında. Bu işlevi küçük bir kaç işlemle sağlayabiliriz. Örneğin;
- 1 ile n(>1) arasında bir sayı üretmek için;
(n * Rnd()) + 1)
- 1 ile n(>1) arasında bir tam sayı üretmek için ise;
CInt(Int((n * Rnd()) + 1))
işlemleri yeterli olacaktır.
Belirli bir aralıkta tam sayı üretme en çok lazım olan rastgele işlemdir. Rnd() çok basamaklı ondalık bir sayı ürettiği için arka arkaya 1 milyon sayı da üretseniz (fonksiyonu her çalışmasında aynı tohumu kullacak şekilde kullanmadıysanız) büyük ihitimalle elde edeceğiniz 1 milyon sayıdan birbiri ile aynı olan çıkmayacaktır. Ancak küçük bir aralıkta rastgele tam sayı üretmek istiyorsanız ve bunu peş peşe yapmanız(şifre oluşturma vb. işlemlerde olduğu gibi) gerekiyorsa dikkat edilmesi gereken noktalar vardır.
Diyelim ki 1 den 20 ye kadar rastgele bir sayı elde edeceksiniz. Bu durumda Int((n * Rnd()) + 1)şeklinde bir işlem yapmanız gerekir. İşlemi inceleyecek olursanız Rnd fonksiyonundan 1 milyar değişik değer gelebilecek de olsa aralığı küçültmemiz ve tam sayı istememiz yüzünden ancak 20 değişik değer elde edebiliriz. Bu zaten beklenen bir şey çünkü amacımız zaten buydu. Bu konudan bu işlemin peş peşe yapılması gerektiği durumlarda dikkat etmemiz gereken noktayı daha iyi anlatabilmek için bahsettim. Örneğin 1 ile 20 arasında 5 sayı üretecek olsak Rnd() fonksiyonundan dönen sayılar birbirinden farklı görünseler aralarındaki 0,05 (1 / 20) kadarlık bir fark bu sayılardan aynı tam sayının oluşmasına sebep olabilir. 0,208340597 ile 0,249015620 sayılarından 5 tam sayısını elde etmemiz de olduğu gibi.
Bu durumda yazının başında anlattığım şartlara bir de birbirlerinden yeterince farklı olmalarını ifade eden farklılık şartını eklemek gerek diyebilirsiniz am buna gerek yok çünkü aslında tekrarlamazlık şartı bu durum için yeterli.
VbMath sınıfını yeterince inceledik zannedersem. Şimdi de .Net’ te, rastgele işlemlerde kullanabileceğimiz bir diğer sınıf olan Random sınıfını inceleyelim.
• Bu arada hemen belirtteyim Rnd ve Randomize metodlarını daha detaylı incelemek isteyenler Microsoft.VisualBasic isim alanı altındaki VbMath sınıfını Reflector ile açarak inceleyebilirler.
Random Sınıfı (System.Random Class)
Yazının buraya kadar ki bölümünden rastgele işlemlerin nasıl gerçekleştiği hakkında yeterli miktarda bilgi edindiğimiz için Random sınıfını anlatmak daha kısa sürecek. Random sınıfı System isim alanının altında yer alır ve VbMath ile kıyaslandığında biraz daha yeteneklidir. Bunu sınıfta yer alan elemanları incelerken siz de farkedebilirsiniz. Ancak bana sorarsanız, Random ile VbMath arasındaki asıl fark içerdiği metodların statik(shared) olmayışıdır. Yani bu sınıfın metodlarını kullanabilmek için bu sınıftan bir nesne(instance) oluşturmanız gerekmektedir.
Random Sınıfında Bulunan Metodlar
Random()
Bu metod, sistem saatinin tick değerini tohum olarak kullanarak yeni bir Random nesnesi oluşturur.
Random(Seed As Integer)
Bu metod, aldığı seed-tohum- parametresini tohum olarak kullanarak yeni bir Random nesnesi oluşturur.
Next()As Integer
Bu metod, 0’ a eşit ya da 0’ dan büyük ve integer veri tipinin sınırları(integer.maxvalue) içinde rastgele bir tam sayı üretir.
Next(maxValue As Integer) As Integer
Bu metod, 0’ a eşit ya da 0’ dan büyük ve verilen maxValue parametre değerinden küçük rastgele bir tam sayı üretir.
Next(minValue As Integer, maxValue As Integer) As Integer
Bu metod, verilen MinValue değerinden büyük, maxValue değerinden küçük rastgele bir tam sayı üretir.
NextBytes(buffer As Byte())
Bu metod, verilen byte dizisini-array- rastgele değerler ile doldurur.
NextDouble() As Double
Bu metod, 0’ a eşit ya da 0’ dan büyük ve 1’ den küçük rastgele double türünde ondalık bir sayı üretir. Bu metod, daha önce incelediğimiz Rnd metodu ile aynı tipte sayılar döner.
Görüldüğü gibi Random sınıfı rastgele sayı üretiminde bir çok yeteneğe sahiptir. Ayrıca Random sınıfında VbMath’ taki Randomize veya benzeri gizemli bir metod da yoktur. Metodlar gayet açık ve net bu sebeple ufak tefek bir iki şey dışında anlatılacak pek de bir ayrıntı yok. Bu ufak tefek şeye gelirsek.
İlk olarak şunu belirteyim ki Random sınıfının metodları statik değildir. Yani kullanmadan önce sizin bu sınıftan bir nesne oluşturmanız gerekmektedir. Üstüne bu sınıfta Randomize gibi bir metod da olmadığı için ilk tohumu ya siz vereceksiniz ya da sistem saati tohum olarak kullanılacak. Tohumu sizin vereceğiniz durumlarda dikkatli olmanızı öneririm çünkü bildiğiniz gibi aynı tohum aynı seri demektir ve Random nesnenizi kodunuzda hep aynı tohumu alacak şekilde kullanırsanız rastgelelikten söz edilemeyeceği gibi tahmin edilebilir şifreler, birbirisinin aynısı üye kodları gibi sorunlarla karşılaşabilirsiniz.
Peş peşe bir çok kez rastgele sayı üreteceğiniz zaman ve her birisi için tekrar Random nesnesi oluşturuyorsanız ve bu nesneler tohumlarını sistem saatinden alıyorsa başaınız dertte demektir. Çünkü çok kısa aralıklarla sistem saatinden alınan tohumlar birbirine benzer yada aynı sonuçlar demektir.
Sonuçta özetlemek ve tavsiye vermek adına şunu söyleyebilirim kullanacağınız Random nesnesi mümkün olduğunca uzun ömürlü olsun. Uzun ömürü de şu şekilde ifade edeyim. Aynı konuda rastgele sayılar üretirken 100ms’ den daha kısa aralıklarla Random nesneleri oluşturup kullanmamaya özen gösterin. Bunun için uygulama boyunca ayakta duran bir Random nesnesi oluşturup sürekli aynı nesne de kullanılabilir.
Buraya kadar anlatılanlardan sonra değerlendirmeyi size bırakıyorum.
RNGCryptoServiceProvider Sınıfı
Bu sınıf System.Security.Cryptography isim alanının altında yer alır. RNGCryptoServiceProvider sınıfı, RandomNumberGenerator sınınfından türer ve kriptografik olarak sağlam rastgele sayılar üretmekte kullanılır. Bu sınıfta, rastgele işlemlerde kullanabileceğimiz metodlar şunlardır.
GetBytes(data As Byte())
Bu metod, parametre olarak aldığı data byte dizisini kriptografik olarak güçlü bir rastgele değerler ile doldurur.
GetNonZeroBytes(data As Byte())
Bu metod, parametre olarak aldığı data byte dizisini kriptografik olarak güçlü bir rastgele ve sıfırdan farklı değerler ile doldurur.
Peki, rastgele işlemler için VbMath ve Random sınıfları duruken buna ne gerek vardı diyebilirsiniz. Hatırlarsanız Rnd()' yi anlatırken güvenliğin hat safhada olduğu işlerde kullanılamayacağından bahsetmiştim. İşte bu sınıf bu eksiğigidermek için hazırlanmıştır. Çalışma şekli farklı olduğu için birisinin üreteceğiniz rastgelesayıları kestirmesi zordur.
Pratik hayattan örnekler vermek gerekirse şifre, üye kodu ve benzeri güvenlik amaçlı rastgele sayı ve kod üretiminde işimize yarar.
Son Söz
Bu makalede .Net ortamında en sık kullanılan rastgele konulu sınıf ve ilgili metodlarını inceledik. Bahsi geçen sınıflar, alt tarafta çok sağlam bir matematik bilgisi ile üretilmiş algoritmalar kullanmaktadılar. Ancak dikkat ettiyseniz bu makalede çok fazla kod öreğine yer vermedim. Onun yerine rastgeleliğin mantığını anlatmaya çalışarak kendi ihtiyaçlarınıza göre kendi çözümlerinizi üretebilmenizi sağlamaya çalıştım.
Ayrıca bildiğiniz gibi programcılık sınırları olan bir kavram değil ve rastgelelik konusunda da bu makalede bahsedilen sınıflar dışında bu sınıfların türediği sınıfları kullanarak kendi rastgele sınıflarınızı oluşturabilirsiniz. Hatta ihtiyacınız olan rastgele şey için ama basit ama karmaşık tamamen sizin yazacağınız bir sınıfı da kullanabilirsiniz. Sonuçta burada .Net' te hazır olarak bulunan rastgele sınıfları inceledik ve güvenlik, hız vb konularda farklılık gösteren bir çok rastgele algoritması vardır ve bunlardan beğendiğiniz birisine de uygulayabilirsiniz.
Bu makalede rastgele işlemler ile ilgili kavramsal ve temel bilgiler verildi. Yazının başında söylediğim gibi "Rastgele Metin" üretimi konulu diğer bir yazımda konu ile ilgili bir çok örnek bulunduğu için bu yazıda anlatılan sınıfların kullanımı hakkında pek örnek vermedim. Bu yazıda öğrendiklerinizi pratik olarak da pekiştirmek için "Rastgele Metin(Üye Kodu, Şifre vb) Üretmek" adlı yazımı okumanızı şiddetle tavsiye ederim.