crypto/rand.Int în Go

Returnează un număr aleatoriu sigur, uniform în intervalul [0, max), ca *big.Int; bun pentru coduri PIN și OTP.

Sintaxă
func Int(rand io.Reader, max *big.Int) (n *big.Int, err error)

Ce face crypto/rand.Int

rand.Int(rand.Reader, big.NewInt(1000000)) returnează un număr între 0 și 999999, ales uniform (fiecare valoare are aceeași șansă) dintr-o sursă sigură. Primul argument este sursa de aleatoriu: dai rand.Reader, generatorul sigur al pachetului. Rezultatul este un *big.Int (pachetul math/big); îl transformi în int64 cu n.Int64().

Este potrivit pentru coduri de verificare trimise prin SMS sau e-mail, alegerea sigură dintr-o listă sau generarea de parole temporare. Funcția se oprește cu panică dacă max <= 0.

Parametri

Parametru Descriere
rand Sursa de octeți aleatorii; folosește rand.Reader.
max Limita superioară, exclusă (*big.Int mai mare decât 0).

Ce returnează

Numărul (*big.Int) și o eroare.

Exemple

Exemplul 1: Valorile rămân mereu în interval

package main

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

func main() {
	max := big.NewInt(6) // zar: 0..5, apoi +1
	aparitii := make([]int, 7)
	for range 6000 {
		n, err := rand.Int(rand.Reader, max)
		if err != nil {
			fmt.Println(err)
			return
		}
		aparitii[n.Int64()+1]++
	}
	inInterval := true
	for fata := 1; fata <= 6; fata++ {
		if aparitii[fata] < 800 || aparitii[fata] > 1200 {
			inInterval = false
		}
	}
	fmt.Println("Toate fețele au apărut de aproximativ 1000 de ori:", inInterval)
	fmt.Println("Valori în afara 1..6:", aparitii[0])
}

Rezultat

Toate fețele au apărut de aproximativ 1000 de ori: true
Valori în afara 1..6: 0

Exemplul 2: Cod de verificare din 6 cifre

Codul diferă la fiecare rulare. %06d păstrează zerourile de la început.

package main

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

func main() {
	n, err := rand.Int(rand.Reader, big.NewInt(1_000_000))
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Printf("Codul tău de verificare este %06d\n", n.Int64())
}

Rezultat posibil (diferă la fiecare rulare)

Codul tău de verificare este 048213

Greșeli frecvente

  • Generezi un cod cu valoare % 1000000 pe octeți aleatorii: unele valori ies mai des decât altele. rand.Int dă o distribuție uniformă.
  • Afișezi codul cu %d: codul 048213 apare ca 48213 și utilizatorul crede că lipsește o cifră.

Comenzi înrudite

  • crypto/rand.Read: Umple un slice cu octeți aleatorii siguri criptografic, luați de la sistemul de operare (chei, tokenuri, sare).
  • crypto/rand.Text: Returnează un text aleatoriu sigur (26 de caractere A-Z și 2-7, cel puțin 128 de biți), gata de folosit ca token sau secret.
  • crypto/rand.Prime: Generează un număr prim aleatoriu cu exact numărul de biți cerut (cu probabilitate foarte mare de a fi prim).