2011-05-30 29 views
28

Estoy tratando de generar números aleatorios (enteros) en Go, inútilmente. Encontré el paquete rand en crypto/rand, que parece ser lo que quiero, pero no puedo decir de la documentación cómo usarlo. Esto es lo que estoy tratando en este momento:Generando Números Aleatorios en Go

b := []byte{} 
    something, err := rand.Read(b) 
    fmt.Printf("something = %v\n", something) 
    fmt.Printf("err = %v\n", err) 

Pero, por desgracia esto siempre da salida:

something = 0 
    err = <nil> 

¿Hay una manera de solucionar este problema por lo que en realidad genera números aleatorios? Alternativamente, ¿hay alguna manera de establecer el límite superior en los números aleatorios que esto genera?

+0

yo esperaría que la rutina para llenar la matriz 'B' con bytes aleatorios, sin embargo muchos que pidió. – sarnold

+0

Yo también: soy nuevo en Go y no estoy familiarizado con las convenciones de llamadas o similares. –

+1

Va a llenar 'b', sin embargo,' b' es una porción vacía (y la matriz de respaldo tiene el tamaño 0). Entonces rand.Read() no tiene espacio para almacenar nada, y devuelve 0 en su variable 'something' que indica que no se almacenó nada. 'b: = make ([] byte, 4)' hubiera sido más apropiado, permitiendo rand.Leer para almacenar 4 bytes en b – nos

Respuesta

24

crypto/rand sólo proporciona flujo binario de datos aleatorios, pero se puede leer números enteros de ella usando encoding/binary:

package main 

import "encoding/binary" 
import "crypto/rand" 

func main() { 
    var n int32 
    binary.Read(rand.Reader, binary.LittleEndian, &n) 
    println(n) 
} 
+0

Genial, eso funcionó para mí. ¡Gracias! –

+0

debe verificar el error en binario. ¿Leer? – Gabriel

+0

Probé esto en el patio de recreo y siempre obtuve el mismo resultado: https://play.golang.org/p/Bh-f4QEyKf – Karlom

27

Dependiendo de su caso de uso, otra opción es el paquete de math/rand. No hagas esto si estás generando números que deben ser completamente impredecibles. Sin embargo, puede ser útil si necesita obtener resultados que sean reproducibles: simplemente pase la misma semilla que pasó la primera vez.

Aquí está la "semilla del generador con la hora actual y generar un número" clásico programa:

package main 

import (
    "fmt" 
    "math/rand" 
    "time" 
) 

func main() { 
    rand.Seed(time.Now().Unix()) 
    fmt.Println(rand.Int()) 
} 
16

el 1 de abril de 2012, después del lanzamiento de la versión estable del lang, puede hacer lo siguiente:

 
package main

import "fmt" import "time" import "math/rand"

func main() { rand.Seed(time.Now().UnixNano()) // takes the current time in nanoseconds as the seed fmt.Println(rand.Intn(100)) // this gives you an int up to but not including 100 }

+0

Esto es más o menos lo que espero al pedir números pseudoaleatorios. 'time.Now(). Unix()' no es suficiente como 'UnixNano()' lo hace. – AndrewPK