koddla

Yazılımcıları bilgi ile güçlendirir.

Random modülü

Giriş

Syntax 

  • random.seed(a=None, version=2) (python 3.x)
  • random.getstate()
  • random.setstate(state)
  • random.randint(a, b)
  • random.randrange(stop)
  • random.randrange(start, stop, step=1)
  • random.choice(seq)
  • random.shuffle(x, random=random.random)
  • random.sample(population, k)

Rastgele bir kullanıcı şifresi oluşturma

Rastgele bir kullanıcı şifresi oluşturmak için string modülünde sağlanan sembolleri kullanabiliriz. Daha detaylı söylemek gerekirse noktalama işaretleri için punctuation, harfler için acii_letters, sayılar için ise digits kullanılabilir:

from string import punctuation, ascii_letters, digits

Daha sonra tüm bu sembolleri symbols isimli bir değişkene atayabiliriz:

symbols = ascii_letters + digits + punctuation

Daha az öğeye sahip bir sembol havuzu oluşturmak için ise bunlardan bazılarını kaldıralım.

Bundan sonra random.SystemRandom kullanarak bir şifre oluşturabiliriz. Uzunluğu 10 olan bir şifre için:

secure_random = random.SystemRandom()
password = "".join(secure_random.choice(symbols) for i in range(10))
print(password)  # '^@g;J?]M6e'

Dikkat: Bu rutinler random modülü ile birlikte gelir — örneğin random.choicerandom.randint, vs. — Dolayısıyla kriptografik uygulamalar için uygun değildir.

Arkaplanda ne olduğunu incelersek bu rutinlerin CSPRNG gereksinimlerini sağlamadığını görürüz. Bu nedenle, özellikle, kullanmayı planladığınız şifreleri oluşturmak için bunlardan birini kullanmamalısınız. Bunun aksine, her zaman, yukarıda gösterildiği gibi SystemRandom kullanmalısınız. Ya da Python 3.6 ve sonrası için güvenli kriptografik işlevleri içeren secrets modülü kullanılabilir.

Örneğin “en az bir küçük harf karakteri, en az bir büyük harf karakteri ve en az üç rakam içeren on haneli bir şifre oluşturmak için aşağıdakini kullanabiliriz:

import string
alphabet = string.ascii_letters + string.digits
while True:
    password = ''.join(choice(alphabet) for i in range(10))
    if (any(c.islower() for c in password)
            and any(c.isupper() for c in password)
            and sum(c.isdigit() for c in password) >= 3):
        break

Random ve shuffle, choice, sample işlevleri

shuffle() 

random.shuffle() ile mutable (değiştirilebilir) and indekslenebilir dizileri karıştırabiliriz:

laughs = ["Hi", "Ho", "He"]

random.shuffle(laughs)     
# Shuffle diziyi yerinde karıştırır. 
#Tekrar atama yapmayın: laughs = random.shuffle(laughs) 

print(laughs)
# Çıktı: ["He", "Hi", "Ho"]  
# Rastgele karışım olduğu için çıktı değişiklik gösterir!

choice() 

Bir diziden rastgele bir öğe seçer:

print(random.choice(laughs))
# Çıktı: He                  
# Rastgele karışım olduğu için çıktı değişiklik gösterir!

sample() 

choice‘de olduğu gibi bir dizeden rastgele öğe seçmek için kullanılır. Ancak sample ile kaç tane rastgele öğe seçeceğimizi de belirtebiliriz:

#                   |--dizi--|--sayı--|
print(random.sample(    laughs   ,     1    ))  # Bir öğe seç
# Çıktı: ['Ho']                    
# Rastgele karışım olduğu için çıktı değişiklik gösterir!

sample, aynı öğeyi birden çok kere seçmeyecektir.

print(random.sample(laughs, 3))  # rastgele 3 öğe seç
# Çıktı: ['Ho', 'He', 'Hi']        

print(random.sample(laughs, 4))  # rastgele 4 öğe seç.

ValueError: Sample larger than population

popülasyonumuz istediğimiz sayıdaki rastgele öğeden daha küçük olduğu için hata verecektir.

Rastgele tamsayı ve ondalıklı sayı üretme: randint, randrange, random ve uniform

randint() 

x ve y (x ve y dahil) arasında rastgele sayı oluşturur:

random.randint(x, y)

Örneğin 1 ve 8 arasında sayı üretmek için:

random.randint(1, 8) # Çıktı: 8

randrange() 

random.randrange işlevi range ile aynı syntaxe sahiptir ve random.randint‘in aksine sınırları dahil etmez:

random.randrange(100)       # 0 ile 99 arasında rastgele sayı
random.randrange(20, 50)    # 20 ile 49 arasında rastgele sayı
random.rangrange(10, 20, 3) # 10 ile 19 arasında 3'er atlayarak oluşturulan rastgele sayılar (10, 13, 16 ve 19)

random 

0 ile 1 arasında ondalıklı sayı:

random.random() # Çıktı: 0.66486093215306317

uniform 

x ve y (sınırlar dahil) arasında rastgele ondalıklı sayı:

random.uniform(1, 8) # Çıktı: 3.726062641730108

Tekrarlanabilir rastgele sayı üreteçleri (seed) ve durumlar (state)

Her zaman aynı şekilde rastgele sayılar üretmek için seed ve state kullanılır:

random.seed(5)                  # Sabit bir durum oluştur         
print(random.randrange(0, 10))  # 0 ile 9 arasında rastgele sayı üret
# Çıktı: 9
print(random.randrange(0, 10))
# Çıktı: 4

Seed’i yeniden aynı şekilde tanımlarsak az önce üretilen rastgele seriyi tekrar elde edebiliriz.

random.seed(5)                 # random modülünü aynı sabit duruma getir
print(random.randrange(0, 10))
# Çıktı: 9
print(random.randrange(0, 10))
# Çıktı: 4

Seed aynı şekilde sabitlendiği için elde edeceğimiz değerler her zaman 9 ve 4 olacak. Döndürülen sayıların değer olarak bir önemi yoksa ancak bunların sadece aynı olması önemliyse getstate ve setstate kullanarak bir önceki durumu geri getirebiliriz.

save_state = random.getstate()  # şimdiki durumu al
print(random.randrange(0, 10))
# Çıktı: 5
print(random.randrange(0, 10))
# Çıktı: 8

random.setstate(save_state)     # kaydedilmiş durumu al
print(random.randrange(0, 10))
# Çıktı: 5
print(random.randrange(0, 10))
# Çıktı: 8

Tekrar rastgele seri elde etmek için seed yerine None verilebilir:

random.seed(None)

Ya da seed metodu argüman kullanılmadan çağrılabilir:

random.seed()

Random modülü ile olasılık ve karar verme

Bir olayın olasılığına göre karar vereceğiniz bir metot yazmanız gerekiyorsa aşağıdaki örnek kullanılabilir:

import random

olasilik = 0.3

if random.random() < olasilik:
    print("0.3 ihtimalle olan karar")
else:
    print("0.7 ihtimalle olan karar")

Kriptografik olarak güvenli rastgele sayılar oluşturun

Varsayılan olarak Python random modülü rastgele sayılar oluşturmak için Mersenne Twister PRNG‘yi kullanır. Bu kullanım simülasyonlar gibi uygulamalar için uygun olsa da, daha zorlu ortamlarda güvenlik gereksinimlerini karşılamaz.

Kriptografik olarak güvenli bir pseudorandom sayı oluşturmak için SystemRandom kullanılabilir. Bu şekilde os.urandom kullanılır ve kriptografik olarak güvenli bir pseudorandom sayı jeneratörü elde edilir.

Bu yöntemin en kolay uygulanma yöntemi SystemRandom sınıfını bir kere başlatmaktır. Sınıfla birlikte gelen yöntemler rarndom modülü ile gelenlere benzer.

from random import SystemRandom
secure_rand_gen = SystemRandom()

[0, 20] arasındda 10 haneli bir int dizisi oluşturmak için randrange() kullanılabilir:

print([secure_rand_gen.randrange(10) for i in range(10)])
# [9, 6, 9, 2, 2, 3, 8, 0, 9, 9]

Verilen aralıkta rastgele bir tamsayı oluşturmak için randint:

print(secure_rand_gen.randint(0, 20))
# 5

Diğer metotlar da benzer şekilde çalışacaktır. Bunun nedeni kullanılan arayüzün random ve SystemRandom için aynı olmasıdır. Aradaki fark rakam üreteçlerinin farklı olmasıdır.

Aynı zamanda, os.urandom ile güvenli kriptografik bitler de elde edebilirsiniz.

Bir yanıt yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Back to top