Why this repeats the same random number? - go

I'm new to Go and not sure why it prints the same number for rand.Intn(n int) int for every run:
package main
import (
"fmt"
"math/rand"
)
func main() {
fmt.Println(rand.Intn(10))
}
The docs says :
Intn returns, as an int, a non-negative pseudo-random number in [0,n) from the default Source. It panics if n <= 0.
And how do I properly seed the random number generation?

By calling the rand.Seed() function, passing it a (random) seed (typically the current unix timestamp). Quoting from math/rand package doc:
Top-level functions, such as Float64 and Int, use a default shared Source that produces a deterministic sequence of values each time a program is run. Use the Seed function to initialize the default Source if different behavior is required for each run.
Example:
rand.Seed(time.Now().UnixNano())
If rand.Seed() is not called, the generator behaves as if seeded by 1:
Seed uses the provided seed value to initialize the default Source to a deterministic state. If Seed is not called, the generator behaves as if seeded by Seed(1).

package main
import
(
"fmt"
"math/rand"
"time"
)
func randomGen(min, max int) int {
rand.Seed(time.Now().Unix())
return rand.Intn(max - min) + min
}
func main() {
randNum := randomGen(1, 10)
fmt.Println(randNum)
}

Under the package, math/rand, you can find a type Rand.
func New(src Source) *Rand - New returns a new Rand that uses random
values from src to generate other random values.
It actually needs a seed to generate it.
step 1: create a seed as a source using new Source.
time.Now().UnixNano() is used for the accuracy.
step 2: create a
type Rand from the seed
step 3: generate a random number.
Example:
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
source := rand.NewSource(time.Now().UnixNano())
r := rand.New(source)
fmt.Println(r.Intn(100))
}

Related

Golang: How to generate random float using only crypto/rand

I'm using gosec to check if my code has any security flaws. But it is reporting the use of math/rand (Use of weak random number generator (math/rand instead of crypto/rand)) pkg in this code:
package main
import (
"fmt"
"math/rand"
)
func main() {
a := rand.Float64()
fmt.Println(a)
}
The problem is: crypto/rand does not have the option to get a random float: https://pkg.go.dev/crypto/rand
How can I do that?

golang rand.Int(). Why every time same values? [duplicate]

This question already has answers here:
Why this repeats the same random number?
(3 answers)
Closed 1 year ago.
I have a code:
package main
import ("fmt"
"math/rand"
"strconv"
)
func main() {
fmt.Println(strconv.Itoa(rand.Int()))
fmt.Println(strconv.Itoa(rand.Int()))
fmt.Println(strconv.Itoa(rand.Int()))
fmt.Println(strconv.Itoa(rand.Int()))
fmt.Println(strconv.Itoa(rand.Int()))
fmt.Println(strconv.Itoa(rand.Int()))
fmt.Println(strconv.Itoa(rand.Int()))
fmt.Println(strconv.Itoa(rand.Int()))
fmt.Println(strconv.Itoa(rand.Int()))
fmt.Println(strconv.Itoa(rand.Int()))
fmt.Println(strconv.Itoa(rand.Int()))
fmt.Println(strconv.Itoa(rand.Int()))
fmt.Println(strconv.Itoa(rand.Int()))
fmt.Println(strconv.Itoa(rand.Int()))
}
When I run it (go run code.go), I get every time same values:
5577006791947779410
8674665223082153551
6129484611666145821
4037200794235010051
3916589616287113937
6334824724549167320
605394647632969758
1443635317331776148
894385949183117216
2775422040480279449
4751997750760398084
7504504064263669287
1976235410884491574
3510942875414458836
Second try:
package main
import ("fmt"
"math/rand"
"strconv"
)
func main() {
fmt.Println(strconv.Itoa(rand.Intn(100)))
fmt.Println(strconv.Itoa(rand.Intn(100)))
fmt.Println(strconv.Itoa(rand.Intn(100)))
fmt.Println(strconv.Itoa(rand.Intn(100)))
fmt.Println(strconv.Itoa(rand.Intn(100)))
fmt.Println(strconv.Itoa(rand.Intn(100)))
fmt.Println(strconv.Itoa(rand.Intn(100)))
}
Same behaviour. Every time's
81
87
47
59
81
18
25
Is this a joke? Why it happens?
Here is no description about non-random same result.
I can see only pseudo-random term without explanation what that means.
Looks like even bash is more logical and stable...
This is a C way
You need to seed it. It says right in the docs
Random numbers are generated by a Source. Top-level functions, such as Float64 and Int, use a default shared Source that produces a deterministic sequence of values each time a program is run. Use the Seed function to initialize the default Source if different behavior is required for each run.
Generally
rand.Seed(time.Now().UnixNano())
You don't appear to have called Seed for math/rand before using the generator.
If Seed is not called, the generator behaves as if seeded by Seed(1). That is not a joke - actually for a PRNG to be deterministic and repeatable is desirable in many cases.
For different numbers, seed with a different value, such as time.Now().UnixNano().
Addition to the other answers, good explanation found about this in medium article go-how-are-random-numbers-generated
Go implements two packages to generate random numbers:
a pseudo-random number generator (PRNG) in the package math/rand cryptographic
pseudorandom number generator (CPRNG), implemented in crypto/rand
If both generate random numbers, your choice will be based on a
tradeoff between genuinely random numbers and performance.
As other answers explain, math/rand packages populate random numbers reading from a source. So if you need random numbers, you need to set random seed calling rand.Seed()
In other case you can use crypto/rand package to generate random numbers. It generates random numbers which can not be deterministic. But performance is bit lower than math/rand package.
I have added sample code below for that. you can run and see different out put here.
package main
import (
"crypto/rand"
"math/big"
)
func main() {
for i := 0; i < 4; i++ {
n, _ := rand.Int(rand.Reader, big.NewInt(100))
println(n.Int64())
}
}

Use a literal value to refer to constant in Golang

I have defined a constant with a type. I want to use the value of a variable to refer to the constant. (Please refer to the code below).
One way would be to define a map of Key to the required Value. Is there another approach to do this ?
import (
"fmt"
"reflect"
)
type Code int
const (
MY_CONST_KEY Code = 123
)
func main() {
x := "MY_CONST_KEY"
//Fetch Value of x as 123
}
There is no way to do what you are asking. You cannot pass constants to the reflect package without instead passing their literal value.
As you correctly mentioned, you can use a map:
package main
import "fmt"
type Code int
var codes = map[string]Code{
"MY_CONST_KEY": 123,
"ANOTHER_CONST_KEY": 456,
}
func main() {
x := codes["MY_CONST_KEY"]
fmt.Println(x)
}
If you make sure the map is not exported (lower case c in codes), then it will only be available inside your package, so consumers of your package cannot modify the map at runtime.
Instead of assigning x to a string, "MY_CONST_KEY", you can do x := MY_CONST_KEY
package main
import (
"fmt"
)
type Code int
const (
MY_CONST_KEY Code = 123
)
func main() {
x := MY_CONST_KEY
fmt.Println(x) // This fetch the value of x as 123
}
One way would be to define a map of Key to the required Value.
Yes, do that.
Is there another approach to do this ?
No.

Change hex to string

I'm going through the Golang tutorial, and I am on this part
package main
import (
"fmt"
"math/rand"
)
func main() {
fmt.Println("My favorite number is", rand.Seed)
}
This returns My favorite number is 0xb1c20
I have been reading on https://golang.org/pkg/math/rand/#Seed but I'm still a bit confused as to how have it instead of show the hex show a string
math/rand.Seed is a function; you are printing the function's location in memory. You probably meant to do something like the following:
package main
import (
"fmt"
"math/rand"
)
func main() {
rand.Seed(234) // replace with your seed value, or set the seed based off
// of the current time
fmt.Println("My favorite number is", rand.Int())
}

How should Go library code initialize and use random number generation?

When writing a Go library that needs to use random numbers, what is the best way to initialize and consume random numbers?
I know that the std way to do this in an application is:
import (
"math/rand"
"time"
)
// do the initial seeding in an init fn
func init() {
// set the global seed and use the global fns
rand.Seed(time.Now().UTC().UnixNano())
}
func main() {
fmt.Println(rand.Int())
fmt.Println(rand.Intn(200))
}
So when I'm writing library code (not in the main package), should I just do the same:
package libfoo
func init() {
rand.Seed(time.Now().UTC().UnixNano())
}
func AwesomeFoo() {
r := rand.Intn(1000)
// ...
}
The application using my library might also do its own random number seeding and use rand.Intn, so my question really is - is there any downside to having a library seed the random number generator and some app code (or another library) do so as well?
Also is there any issue with the library using the "global" rand.Intn or rand.Int or should a library create it's own private Rand object via rand.New(src) and use that instead?
I don't have any particular reason for thinking this is unsafe, but I know enough about crypto and PRNGs to know that it is easy to get something wrong if you don't know what you're doing.
For example, here's a simple library for the Knuth (Fisher-Yates) shuffle that needs randomness: https://gist.github.com/quux00/8258425
What's best really just depends on the type of application you're writing and the type of library you want to create. If we're not sure, we can get the most flexibility by using a form of dependency injection through Go interfaces.
Consider the following naive Monte Carlo integrator that takes advantage of the rand.Source interface:
package monte
import (
"math/rand"
)
const (
DEFAULT_STEPS = 100000
)
type Naive struct {
rand *rand.Rand
steps int
}
func NewNaive(source rand.Source) *Naive {
return &Naive{rand.New(source), DEFAULT_STEPS}
}
func (m *Naive) SetSteps(steps int) {
m.steps = steps
}
func (m *Naive) Integrate1D(fn func(float64) float64, a, b float64) float64 {
var sum float64
for i := 0; i < m.steps; i++ {
x := (b-a) * m.rand.Float64()
sum += fn(x)
}
return (b-a)*sum/float64(m.steps)
}
We can then use this package to calculate the value of pi:
func main() {
m := monte.NewNaive(rand.NewSource(200))
pi := 4*m.Integrate1D(func (t float64) float64 {
return math.Sqrt(1-t*t)
}, 0, 1)
fmt.Println(pi)
}
In this case, the quality of our algorithm's results depend on the type of pseudorandom number generator used, so we need to provide a way for users to swap out one generator for another. Here we've defined an opaque type that takes a random number source in its constructor. By having their random number generator satisfy the rand.Source interface, our application writer can then swap out random number generators as needed.
However, there are many cases where this is exactly what we don't want to do. Consider a random password or key generator. In that case, what we really want is a high entropy source of truly random data, so we should just use the crypto/rand package internally and hide the details from our application writers:
package keygen
import (
"crypto/rand"
"encoding/base32"
)
func GenKey() (string, error) {
b := make([]byte, 20)
if _, err := rand.Read(b); err != nil {
return "", err
}
enc := base32.NewEncoding("ABCDEFGHIJKLMNOPQRSTUVWXYZ346789")
return enc.EncodeToString(b), nil
}
Hopefully that helps you make a decision. If the code is for your own applications or applications within a specific company rather than industry wide or public use, lean towards the library design that exposes the fewest internals and creates the fewest dependencies rather than the most general design, since that will ease maintenance and shorten implementation time.
Basically, if it feels like overkill, it probably is.
In the case of the Knuth Shuffle, the requirements are simply a decent psuedo-random number generator, so you could simply use an internally seeded rand.Rand object that's private to your package like so:
package shuffle
import (
"math/rand"
"time"
)
var r *rand.Rand
func init() {
r = rand.New(rand.NewSource(time.Now().UTC().UnixNano()))
}
func ShuffleStrings(arr []string) {
last := len(arr)-1
for i := range arr {
j := r.Intn(last)
arr[i], arr[j] = arr[j], arr[i]
}
}
Then the application doesn't have to worry about how it works:
package main
import (
"shuffle"
"fmt"
)
func main() {
arr := []string{"a","set","of","words"}
fmt.Printf("Shuffling words: %v\n", arr)
for i := 0; i<10; i++ {
shuffle.ShuffleStrings(arr)
fmt.Printf("Shuffled words: %v\n", arr)
}
}
This prevents the application from accidentally reseeding the random number generator used by your package by calling rand.Seed.
Don't seed the global random number generator. That should be left to package main.
If you care what your seed is, you should create your own private Rand object. If you don't care, you can just use the global source.
If you care about your numbers actually being random, you should use crypto/rand instead of math/rand.

Resources