rand.Intn generating same random sequences multiple time [duplicate] - go

This question already has answers here:
Go rand.Intn same number/value
(3 answers)
Closed 2 years ago.
I am trying to write a function that generates a random sequence with an alphanumeric character, Unfortunately, the function returns the same random sequence when calling multiple times.
I even tried by seeding the rand with time.Now().UTC().UnixNano(), even though getting the same values again and again
Main Package:
package main
import (
"fmt"
"time"
"userpkg/random"
)
func main() {
fmt.Println(random.RandomHash(32))
fmt.Println(random.RandomHash(32))
fmt.Println(random.RandomHash(32))
fmt.Println(random.RandomHash(32))
}
Random Package
package random
func RandomHash(length int8) string {
rand.Seed(time.Now().UTC().UnixNano())
pool := []byte(`0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ`)
/* allocate a new slice array to store the hash */
buf := make([]byte, length)
for i := int8(0); i < length; i++ {
buf[i] = pool[rand.Intn(len(pool))]
}
rand.Shuffle(len(buf), func(i, j int) {
buf[i], buf[j] = buf[j], buf[i]
})
str := string(buf)
return str
}
Output :
Aau9hmA3YpDezPMIFUtgSUoQfwi7KuWK
Aau9hmA3YpDezPMIFUtgSUoQfwi7KuWK
Aau9hmA3YpDezPMIFUtgSUoQfwi7KuWK
Aau9hmA3YpDezPMIFUtgSUoQfwi7KuWK
Please guide me on how to solve this issue, Thanks

You need to seed the math/rand package once only. If you call the RandomHash() function "very fast", you will seed it to the same value, so it will use the same random values, resulting in the same result! On top of this, on the Go Playground the time is deterministic (it doesn't elapse unless e.g. time.Sleep() is called!).
Move the seeding outside of RandomHash(), e.g. to a package init() function:
func init() {
rand.Seed(time.Now().UnixNano())
}
func RandomHash(length int8) string {
// ...
}
Then each return value of RandomHash() will (likely) be different, e.g. (try it on the Go Playground):
Aau9hmA3YpDezPMIFUtgSUoQfwi7KuWK
8XhJlp6EAXqqbEcPLQL83pw8wUiJRl7D
HGWpHldhGWpzl2KY10ua15T04N1eoPp7
huRNzf4eD7IIuqYNjoMZB5z6r0RFRB64
Also see related question:
How to generate a random string of a fixed length in Go?

Related

Why is the slice field of a struct not appended to? [duplicate]

This question already has answers here:
Assign a new value to a struct field
(2 answers)
Closed 10 months ago.
The output of the following code surprises me:
package main
import (
"fmt"
)
type Thing struct {
mappings map[string]int
orderings []string
}
func NewThing() Thing {
t := Thing{}
t.mappings = make(map[string]int)
return t
}
func (t Thing) Add(s string) {
t.mappings[s] = 1
t.orderings = append(t.orderings, s)
}
func main() {
t := NewThing()
t.Add("foo")
if len(t.mappings) == len(t.orderings) {
fmt.Printf("Equal lengths: %v versus %v", t.mappings, t.orderings)
} else {
fmt.Printf("Unequal lengths: %v versus %v", t.mappings, t.orderings)
}
}
When run on the playground (https://play.golang.org/p/Ph67tHOt2Z_I) the output is this:
Unequal lengths: map[foo:1] versus []
I believe I'm treating the slice correctly; from my understanding it is initialized to nil in NewThing(), and is appended to in Add() (ensuring that the value returned from append is only assigned to its first argument).
Am I missing something incredibly obvious?
I looked at the following resources for an explanation:
https://gobyexample.com/slices - only uses either slice literals (i.e. not a struct field) or slices with set capacities, and I will not know the final size of t.orderings. It's my understanding that append should perform the extension and allocation automatically.
https://go.dev/blog/slices-intro - again, all demonstrations use slice literals. If the fields are moved out of the struct things work as expected. It's only once in the struct that this behavior occurs.
https://yourbasic.org/golang/gotcha-append/ - while it does describe behavior where append does not work as expected, the explanation involves append reusing memory when the slice has enough capacity for a new element, causing unexpected behavior when attempts to append the same array to two different copies. In my case, there is no reassignment of slice operations such as the one in this article, which is discouraged (some_var = append(some_other_var, elem)).
And I looked at the following questions for inspiration:
Go - append to slice in struct: the solution to this question was to assign the result of append back to the field, which I have done.
Correct way to initialize empty slice: the explanation is that slices don't have to be initialized, and can be left as nil and "appended to with allocation", so I believe I'm fine not initializing Thing.orderings.
Incase you don't want to use a pointer ,you can declare a global variable for Thing struct and assign it with the value of t from add function.Here is the code for the same logic :
package main
import (
"fmt"
)
var thing Thing
type Thing struct {
mappings map[string]int
orderings []string
}
func NewThing() Thing {
t := Thing{}
t.mappings = make(map[string]int)
return t
}
func (t Thing) Add(s string) {
t.mappings[s] = 1
t.orderings = append(t.orderings, s)
thing = t
}
func main() {
t := NewThing()
t.Add("foo")
if len(thing.mappings) == len(thing.orderings) {
fmt.Printf("Equal lengths: %v versus %v", thing.mappings, thing.orderings)
} else {
fmt.Printf("Unequal lengths: %v versus %v", thing.mappings, thing.orderings)
}
}
Output:
Equal lengths: map[foo:1] versus [foo]

Why [capacity]string assert to []string will be failed in Golang?

I am using Golang1.14.
Here is the test code.
package main
import "time"
func checkData(data interface{}) {
if _, ok := data.([]string); ok {
println("Assert true.")
} else {
println("Assert false.")
}
}
func main() {
var years [20]string
for i := 0; i < 20; i++ {
years[i] = string(time.Now().Year() - 10 + i)
}
checkData(years)
foods := []string{"Fruit", "Grass", "Fish", "Meat"}
checkData(foods)
}
The output is:
Assert false.
Assert true.
I am new to Golang and really confusing that [20]string is not a []string.Can someone tell me why?Thanks.
[20]string is an array. It is a type that contains 20 strings, and if you pass it as an interface{}, you can recover it using intf.([20]string).
[]string is a slice. It has a backing array, but it is essentially a view over an array. You assertion checks if the interface is a slice, so this one works.
Arrays and slices are different things in Go. An array is a data type with a fixed size. For instance:
func f(arr [10]int) {...}
You can only call f with an int array of size 10. When you do call it, the array will be passes as value, so the function will get a copy of the array, all 10 members of it. But:
func f(arr []int) {...}
You can call f with any size of slice. A slice contains a reference to its underlying array, so an array copy will not take place here. You cannot call thisf` with an array.

Is json marshalling of map stable in Go? [duplicate]

This question already has answers here:
How to produce JSON with sorted keys in Go?
(2 answers)
Closed 3 years ago.
I am writing code that will check if data changed based on a comparison of json.Marshaled hashes of maps. I've created small code to produce what I am doing in abstracted way (available also in playground)
package main
import (
"crypto/sha256"
"encoding/hex"
"encoding/json"
"fmt"
)
func main() {
fmt.Println("Hello, playground")
a := make(map[string]string)
a["a"] = "a1"
a["b"] = "b2"
sa, _ := json.Marshal(a)
ha := GenerateSHA256Hash(string(sa))
b := make(map[string]string)
b["a"] = "a1"
b["b"] = "b2"
sb, _ := json.Marshal(b)
hb := GenerateSHA256Hash(string(sb))
fmt.Println(ha)
fmt.Println(hb)
fmt.Println(ha == hb)
}
func GenerateSHA256Hash(s string) string {
hasher := sha256.New()
hasher.Write([]byte(s))
return hex.EncodeToString(hasher.Sum(nil))
}
But I recall that order of maps are unordered and in Golang spec it's written that
The iteration order over maps is not specified and is not guaranteed to be the same from one iteration to the next. If a map entry that has not yet been reached is removed during iteration, the corresponding iteration value will not be produced. If a map entry is created during iteration, that entry may be produced during the iteration or may be skipped. The choice may vary for each entry created and from one iteration to the next. If the map is nil, the number of iterations is 0.
So, in the code above I am building map, in the same way, each time and not accessing it concurrently during json.Marshalling.
Question: Will the hashes, produced in such manner, be always equal? Or will this approach be stable?
Go spec in this case is irrelevant since it's a details of the Go standard library (the encoding/json module)
As of this very moment it's implemented as
// Extract and sort the keys.
keys := v.MapKeys()
sv := make([]reflectWithString, len(keys))
for i, v := range keys {
sv[i].v = v
if err := sv[i].resolve(); err != nil {
e.error(fmt.Errorf("json: encoding error for type %q: %q", v.Type().String(), err.Error()))
}
}
sort.Slice(sv, func(i, j int) bool { return sv[i].s < sv[j].s })
Additionally, given the encoding/json documentation says
The map keys are sorted and used as JSON object keys by applying the following rules, subject to the UTF-8 coercion described for string values above:
it's safe to expect the same hash until at least Go 2.

How can I cast from []interface{} to []int? [duplicate]

This question already has answers here:
Type converting slices of interfaces
(9 answers)
Closed 7 years ago.
I would like to get non duplicated []int.
I'm using set, but I don't know how to get []int from set.
How can I do that?
package main
import (
"fmt"
"math/rand"
"time"
"github.com/deckarep/golang-set"
)
func pickup(max int, num int) []int {
set := mapset.NewSet()
rand.Seed(time.Now().UnixNano())
for set.Cardinality() < num {
n := rand.Intn(max)
set.Add(n)
}
selected := set.ToSlice()
// Do I need to cast from []interface{} to []int around here?
// selected.([]int) is error.
return selected
}
func main() {
results := pickup(100, 10)
fmt.Println(results)
// some processing using []int...
}
There is no automatic way to do that. You need to create an int slice and copy into it:
selected := set.ToSlice()
// create a secondary slice of ints, same length as selected
ret := make([]int, len(selected))
// copy one by one
for i, x := range selected {
ret[i] = x.(int) //provided it's indeed int. you can add a check here
}
return ret

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