Generating a random number in a custom range - go

I have go script that starts on "localhost:8080/1" with a previous and next links I need to add Random link with custom range that I can change like:
small numbers like 100 to 200 "localhost:8080/100 - 200" and
even to big number like: "16567684686592643791596485465456223131545455682945955"
So:
// Get next and previous page numbers
previous := new(big.Int).Sub(page, one)
next := new(big.Int).Add(page, one)
random :=????

You need to use the package crypto.rand Int() function, which does support big.Int (as opposed to the math.rand package)
See this article (and its playground example):
package main
import (
"fmt"
"math/big"
"crypto/rand"
)
func main() {
var prime1, _ = new(big.Int).SetString("21888242871839275222246405745257275088548364400416034343698204186575808495617", 10)
// Generate random numbers in range [0..prime1]
// Ignore error values
// Don't use this code to generate secret keys that protect important stuff!
x, _ := rand.Int(rand.Reader, prime1)
y, _ := rand.Int(rand.Reader, prime1)
fmt.Printf("x: %v\n", x)
fmt.Printf("y: %v\n", y)
}

Related

string to big Int in Go?

Is there a way to convert a string (which is essentially a huge number) from string to Big int in Go?
I tried to first convert it into bytes array
array := []byte(string)
Then converting the array into BigInt.
I thought that worked, however, the output was different than the original input. So I'm guessing the conversion didn't do the right thing for some reason.
The numbers I'm dealing with are more than 300 digits long, so I don't think I can use regular int.
Any suggestions of what is the best approach for this?
Package big
import "math/big"
func (*Int) SetString
func (z *Int) SetString(s string, base int) (*Int, bool)
SetString sets z to the value of s, interpreted in the given base, and
returns z and a boolean indicating success. The entire string (not
just a prefix) must be valid for success. If SetString fails, the
value of z is undefined but the returned value is nil.
The base argument must be 0 or a value between 2 and MaxBase. If the
base is 0, the string prefix determines the actual conversion base. A
prefix of “0x” or “0X” selects base 16; the “0” prefix selects base 8,
and a “0b” or “0B” prefix selects base 2. Otherwise the selected base
is 10.
For example,
package main
import (
"fmt"
"math/big"
)
func main() {
n := new(big.Int)
n, ok := n.SetString("314159265358979323846264338327950288419716939937510582097494459", 10)
if !ok {
fmt.Println("SetString: error")
return
}
fmt.Println(n)
}
Playground: https://play.golang.org/p/ZaSOQoqZB_
Output:
314159265358979323846264338327950288419716939937510582097494459
See Example for string to big int conversion.
package main
import (
"fmt"
"log"
"math/big"
)
func main() {
i := new(big.Int)
_, err := fmt.Sscan("18446744073709551617", i)
if err != nil {
log.Println("error scanning value:", err)
} else {
fmt.Println(i)
}
}
Output:
18446744073709551617

Convert feet and inches to centimeters in Go?

I am new to Go and I am a bit stuck on a problem regarding human height conversion from feet/inches to cm.
How can I convert, in an efficient way, a string that looks like this 5'2'' to an centimeter int?
Edit:
After some more testing I ended up with this solution. How can it be improved?
height := strings.Split("5'2''", "'")
heightfeet,err :=strconv.ParseFloat(height[0],10)
heightinch,err :=strconv.ParseFloat(height[1],10)
heightcm :=heightfeet*30.48+heightinch*2.54
I feel like your approach is fine, but, if you actually want to be sure to extract only the integers and using constants take a look at this Go Playground I set up.
package main
import (
"fmt"
"regexp"
"strconv"
)
func main() {
//Defining our constants
const cm1 = 30.48
const cm2 = 2.54
//Slice to contain parsed ints
var parsedTokens []float64
feet := "5'2''"
//Regex to extract only integers
reg := regexp.MustCompile("[0-9]+")
filtered:= reg.FindAllString(feet, -1)
//Parse each value v in filtered and append it into parsedTokens
for _, v := range filtered {
k, _ := strconv.ParseFloat(v, 64)
parsedTokens = append(parsedTokens, k)
}
//157.48000000000002
fmt.Println(parsedTokens[0]*cm1 + parsedTokens[1]*cm2)
}

Go how to properly use the for ... range loop

At the moment I have a go program that contains the following code.
package main
import "time"
import "minions/minion"
func main() {
// creating the slice
ms := make([]*minion.Minion, 2)
//populating the slice and make the elements start doing something
for i := range ms {
m := &ms[i]
*m = minion.NewMinion()
(*m).Start()
}
// wait while the minions do all the work
time.Sleep(time.Millisecond * 500)
// make the elements of the slice stop with what they were doing
for i := range ms {
m := &ms[i]
(*m).Stop()
}
}
Here NewMinion() is a constructor that returns a *minion.Minion
The code works perfectly, but having to write m := &ms[i] every time I use a for ... range loop seems to me like there should be a code writer friendlier way to tackle this problem.
Ideally I'd like something like the following to be possible (using the made up &range tag):
package main
import "time"
import "minions/minion"
func main() {
// creating the slice
ms := make([]*minion.Minion, 2)
//populating the slice and make the elements start doing something
for _, m := &range ms {
*m = minion.NewMinion()
(*m).Start()
}
// wait while the minions do all the work
time.Sleep(time.Millisecond * 500)
// make the elements of the slice stop with what they were doing
for _, m := &range ms {
(*m).Stop()
}
}
Unfortunately, this is not a language feature as of yet. Any considerations on what would be the nicest way remove the m := &ms[i] from the code? Or is there no way yet that takes less effort to write than this?
Your first example is a slice of pointers, you don't need to take the address of the pointers in the slice and then dereference the pointers each time. More idiomatic Go would look like (edited slightly to run in the playground without the "minion" package):
http://play.golang.org/p/88WsCVonaL
// creating the slice
ms := make([]*Minion, 2)
//populating the slice and make the elements start doing something
for i := range ms {
ms[i] = NewMinion(i)
ms[i].Start()
// (or equivalently)
// m := MewMinion(i)
// m.Start()
// ms[i] = m
}
// wait while the minions do all the work
time.Sleep(time.Millisecond * 500)
// make the elements of the slice stop with what they were doing
for _, m := range ms {
m.Stop()
}
This is all wrong.
There is absolutely no need to take the address of a pointer in your code. ms is a slice of pointers and you constructor returns a pointer so just assign i directly:
for i := range ms {
ms[i] = minion.NewMinion()
ms[i].Start()
}
Dead simple.

Slice unicode/ascii strings in golang?

I need to slice a string in Go. Possible values can contain Latin chars and/or Arabic/Chinese chars. In the following example, the slice annotation [:1] for the Arabic string alphabet is returning a non-expected value/character.
package main
import "fmt"
func main() {
a := "a"
fmt.Println(a[:1]) // works
b := "ذ"
fmt.Println(b[:1]) // does not work
fmt.Println(b[:2]) // works
fmt.Println(len(a) == len(b)) // false
}
http://play.golang.org/p/R-JxaxbfNL
First of all, you should really read about strings, bytes and runes in Go.
And here is how you can achieve what you want: Go playground (I was not able to properly paste arabic symbols, but if Chinese works, arabic should work too).
s := "abcdefghijklmnop"
fmt.Println(s[2:9])
s = "维基百科:关于中文维基百科"
fmt.Println(string([]rune(s)[2:9]))
The output is:
cdefghi
百科:关于中文
You can use the utf8string package:
package main
import "golang.org/x/exp/utf8string"
func main() {
a := utf8string.NewString("🎈🎄🎀🎢👓")
// example 1
r := a.At(1)
// example 2
s := a.Slice(1, 3)
// example 3
n := a.RuneCount()
// print
println(r == '🎄', s == "🎄🎀", n == 5)
}
https://pkg.go.dev/golang.org/x/exp/utf8string

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