Skip to content

Tasodifiy sonlarni hosil qilish


Go dasturlash tilida tasodifiy sonlarni hosil qilishning ikki xil yo'li mavjud:

1. math/rand paketi (tasodifiy sonlar)


Bu paket orqali oddiy tasodifiy sonlar ketma-ketligini olish mumkin. Biroq ular pseudo-random bo'lib, boshlang'ich qiymat (seed) bir xil bo'lsa, natija ham bir xil bo'ladi. Shu sababli, har safar dastur ishga tushirilganda turlicha ketma-ketlik hosil qilish uchun boshlang'ich qiymatni o'rnatish kerak bo'ladi. Odatda buning uchun joriy vaqt ishlatiladi.

Misol:

package main

import (
    "fmt"
    "math/rand"
)

func main() {
    randomNumber := rand.Intn(100) // 0 va 100 orasidagi tasodifiy sonlar.
    fmt.Printf("Tasodifiy son: %d\n", randomNumber)
}

Natija:

Tasodifiy son: 97 

Dasturni har safar ishga tushurganingizda har xil natija olasiz. Shu sababli sizda yuqoridagi natija boshqa chiqishi mumkin.

Endi yuqoridagi misolimizga ozroq o'zgartirish kiritib boshlang'ich qiymat (seed) bilan qanday ishlashini ko'ramiz.

package main

import (
    "fmt"
    "math/rand"
)

func main() {
    rand.Seed(5)
    randomNumber := rand.Intn(100)
    fmt.Printf("Tasodifiy son: %d\n", randomNumber)
}

Natija:

Tasodifiy son: 26

Bu misolda esa sizda ham natija 26 chiqadi. Lekin nima uchun? Quyida shunga to'xtalamiz.

math/rand — pseudo-random generator, ya'ni u aslida formulaga asoslangan hisob-kitoblar orqali tasodifiy sonlar chiqaradi. Seed generatorni boshlang'ich nuqtasi. Agar boshlang'ich nuqta (seed) 5 bo'lsa, algoritm bir xil qadamlar bilan bir xil ketma-ketlikni hisoblaydi. Shuning uchun rand.Seed(5) qo'yilsa, har safar dastur ishlaganda birinchi rand.Intn(100) doim bir xil son bo'ladi. Agar rand.Seed(10) qilinsa, boshqa ketma-ketlik chiqadi, lekin har safar baribir xuddi shu seed = 10 bo'lgani uchun natija o'zgarmaydi. Qiziq tomoni bu barcha kompyuterlarda bir xil natija beradi, CPU yoki operatsion tizimga bog'liq emas.

2. crypto/rand paketi (kriptografik xavfsiz tasodifiy sonlar)


Agar xavfsizlik muhim bo'lsa (masalan, parol yoki shifrlash kalitlarini yaratishda), crypto/rand paketidan foydalanish lozim. Bu paket haqiqiy kriptografik xavfsiz tasodifiy sonlarni hosil qiladi. crypto/rand deterministik emas, ya'ni bir xil seed berish tushunchasi yo'q. Natijalar CPU yoki OS ga qarab o'zgarishi mumkin, chunki u operatsion tizimning ichki entropy (tasodifiylik manbai) dan foydalanadi.

package main

import (
    "crypto/rand"
    "fmt"
    "math/big"
)

func main() {
    num, err := rand.Int(rand.Reader, big.NewInt(101))
    if err != nil {
        fmt.Println("Xatolik:", err)
        return
    }

    fmt.Println("Tasodifiy son:", num)
}

Natija:

16
Har safar ishga tushirganda boshqa natija chiqadi.

Endi bu dasturni bosqichma-bosqich izohlaymiz:

  • math/big katta sonlar (big.Int) bilan ishlash uchun. Chunki crypto/rand.Int faqat *big.Int chegarasigacha son qaytaradi.
  • rand.Int funksiyasi tasodifiy son qaytaradi.
  • rand.Reader bu tasodifiylik manbai (OSdan entropy oladi).
  • big.NewInt(101) yuqori chegarani bildiradi. Bu holda 0 dan 100 gacha son beradi (101 chegarani kiritmaydi, shuning uchun [0, 101). ya'ni 0–100).
  • Funksiya ikki qiymat qaytaradi:
    • num tasodifiy son (*big.Int tipida).
    • err xatolik bo'lsa shu yerda bo'ladi.