go_random/

directory
v0.0.0-...-e6528b1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 1, 2025 License: CC-BY-4.0

README

back to contents

Go: random

↑ top




Reference

↑ top




random integer

Code:

package main

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

func init() {
	rand.Seed(time.Now().UnixNano())
}

func main() {
	src := rand.NewSource(time.Now().UnixNano())
	fmt.Println(src.Int63()) // 8965630292270293660

	random := rand.New(src)
	fmt.Println(random.Int())      // 7742198863449996164
	fmt.Println(random.Int31())    // 1780122247
	fmt.Println(random.Int31n(3))  // 0
	fmt.Println(random.Int63())    // 838216768439018635
	fmt.Println(random.Int63n(10)) // 7
}

↑ top




random float

Code:

package main

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

func init() {
	rand.Seed(time.Now().UnixNano())
}

func main() {
	src := rand.NewSource(time.Now().UnixNano())
	random := rand.New(src)
	fmt.Println(random.Float32())     // 0.7096111
	fmt.Println(random.Float64())     // 0.7267748269300062
	fmt.Println(random.ExpFloat64())  // 1.4478015992783408
	fmt.Println(random.NormFloat64()) // -1.7676830716730048
}

↑ top




random duration

Code:

package main

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

func init() {
	rand.Seed(time.Now().UnixNano())
}

func main() {
	fmt.Println(duration(5*time.Second, 12*time.Second)) // 5.061306405s
}

func duration(min, max time.Duration) time.Duration {
	if min >= max {
		// return a random duration
		return 7*time.Second + 173*time.Microsecond
	}
	src := rand.NewSource(time.Now().UnixNano())
	random := rand.New(src)
	adt := time.Duration(random.Int63n(int64(max - min)))
	return min + adt
}

↑ top




random bytes
package main

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

func main() {
	b := make([]byte, 10)
	if _, err := crand.Read(b); err != nil {
		panic(err)
	}
	fmt.Println(string(b))
	// ��.���ms#

	fmt.Println(string(randBytes(10)))
	// IdPDZOxast

	fmt.Println(multiRandBytes(3, 5))
	// [[119 121 67] [114 70 70] [112 90 100] [74 85 77] [84 101 101]]
}

// http://stackoverflow.com/questions/22892120/how-to-generate-a-random-string-of-a-fixed-length-in-golang
func randBytes(bytesN int) []byte {
	const (
		letterBytes   = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
		letterIdxBits = 6                    // 6 bits to represent a letter index
		letterIdxMask = 1<<letterIdxBits - 1 // All 1-bits, as many as letterIdxBits
		letterIdxMax  = 63 / letterIdxBits   // # of letter indices fitting in 63 bits
	)
	src := rand.NewSource(time.Now().UnixNano())
	b := make([]byte, bytesN)
	// A src.Int63() generates 63 random bits, enough for letterIdxMax characters!
	for i, cache, remain := bytesN-1, src.Int63(), letterIdxMax; i >= 0; {
		if remain == 0 {
			cache, remain = src.Int63(), letterIdxMax
		}
		if idx := int(cache & letterIdxMask); idx < len(letterBytes) {
			b[i] = letterBytes[idx]
			i--
		}
		cache >>= letterIdxBits
		remain--
	}
	return b
}

func multiRandBytes(bytesN, sliceN int) [][]byte {
	m := make(map[string]struct{})
	rs := [][]byte{}
	for len(rs) != sliceN {
		b := randBytes(bytesN)
		if _, ok := m[string(b)]; !ok {
			rs = append(rs, b)
			m[string(b)] = struct{}{}
		} else {
			continue
		}
	}
	return rs
}

↑ top




random select
package main

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

func init() {
	rand.Seed(time.Now().UnixNano())

	// nr := rand.New(rand.NewSource(time.Now().UnixNano()))
	// fmt.Println(nr.Float32())

	// fmt.Println(rand.Float32())
}

func main() {
	ents := []weightEntry{
		{weight: 0.05},
		{weight: 0.8},
		{weight: 0.15},
	}
	wt := createWeightTable(ents)

	fmt.Println(wt.choose())
	fmt.Println(wt.choose())
	fmt.Println(wt.choose())
	fmt.Println(wt.choose())
	fmt.Println(wt.choose())
	fmt.Println(wt.choose())
	fmt.Println(wt.choose())
	fmt.Println(wt.choose())
}

/*
{0.8 }
{0.8 }
{0.15 }
{0.8 }
{0.8 }
{0.8 }
{0.8 }
{0.8 }
*/

type weightEntry struct {
	weight float32
	name   string
}

type weightTable struct {
	entries       []weightEntry
	distributions []float32
}

func (wt weightTable) Len() int           { return len(wt.entries) }
func (wt weightTable) Swap(i, j int)      { wt.entries[i], wt.entries[j] = wt.entries[j], wt.entries[i] }
func (wt weightTable) Less(i, j int) bool { return wt.entries[i].weight < wt.entries[j].weight }

func createWeightTable(entries []weightEntry) *weightTable {
	wt := weightTable{entries: entries}
	sort.Sort(wt)
	var cw float32
	for _, entry := range wt.entries {
		cw += entry.weight
		wt.distributions = append(wt.distributions, cw)
	}
	return &wt
}

func (wt *weightTable) choose() weightEntry {
	entryN := len(wt.entries)
	lastWeight := wt.entries[len(wt.entries)-1].weight
	idx := sort.Search(entryN, func(i int) bool {
		// returns the smallest index, of which distribution is
		// greater than random weight value
		return wt.distributions[i] >= rand.Float32()*lastWeight
	})
	return wt.entries[idx]
}

package main

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

func init() {
	rand.Seed(time.Now().UnixNano())

	// nr := rand.New(rand.NewSource(time.Now().UnixNano()))
	// fmt.Println(nr.Float32())

	// fmt.Println(rand.Float32())
}

func main() {
	ents := []weightEntry{
		{weight: 0.05},
		{weight: 0.8},
		{weight: 0.15},
	}
	wt := createWeightTable(ents)

	fmt.Println(wt.choose())
	fmt.Println(wt.choose())
	fmt.Println(wt.choose())
	fmt.Println(wt.choose())
	fmt.Println(wt.choose())
	fmt.Println(wt.choose())
	fmt.Println(wt.choose())
	fmt.Println(wt.choose())
}

/*
{0.8 }
{0.8 }
{0.8 }
{0.15 }
{0.15 }
{0.8 }
{0.8 }
{0.8 }
*/

type weightEntry struct {
	weight float32
	name   string
}

type weightTable struct {
	entries    []weightEntry
	sumWeights float32
}

func (wt weightTable) Len() int           { return len(wt.entries) }
func (wt weightTable) Swap(i, j int)      { wt.entries[i], wt.entries[j] = wt.entries[j], wt.entries[i] }
func (wt weightTable) Less(i, j int) bool { return wt.entries[i].weight < wt.entries[j].weight }

func createWeightTable(entries []weightEntry) *weightTable {
	wt := weightTable{entries: entries}
	sort.Sort(wt)
	for _, entry := range wt.entries {
		wt.sumWeights += entry.weight
	}
	return &wt
}

func (wt *weightTable) choose() weightEntry {
	v := rand.Float32() * wt.sumWeights
	var sum float32
	var idx int
	for i := range wt.entries {
		sum += wt.entries[i].weight
		if sum >= v {
			idx = i
			break
		}
	}
	return wt.entries[idx]
}

↑ top




Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL