1. 程式人生 > >golang-random隨機數

golang-random隨機數

在Golang中,有兩個包提供了rand,分別為 "math/rand" 和 "crypto/rand",  對應兩種應用場景。

一、"math/rand" 包實現了偽隨機數生成器。也就是生成 整形和浮點型。

   該包中根據生成偽隨機數是是否有種子(可以理解為初始化偽隨機數),可以分為兩類:

  1、有種子。通常以時鐘,輸入輸出等特殊節點作為引數,初始化。該型別生成的隨機數相比無種子時重複概率較低。

  2、無種子。可以理解為此時種子為1, Seek(1)。

 for i := 0; i < 10; i++ {
        r := rand.New(rand.NewSource(time.Now().UnixNano()))
        fmt.Printf(
"%d ", r.Int31()) } fmt.Println("") for i := 0; i < 10; i++ { fmt.Printf("%d ", rand.Int31()) } // 703626706 738454556 1582952585 1585378792 1337824049 728749578 2042459905 780929790 1910510343 178978546 // 1106410694 1747278511 460128162 817455089 683024728 1006933274 607811211 629431445 1458323237 469339106

設定範圍:

// int
func randInt(min int , max int) int {
    return min + rand.Intn(max-min)
}

// float
func randomFloat(min, max int) float64 {
    if max == min {
        return float64(max)
    }
    return decimal(rand.Float64()*(float64(max) - float64(min)) + float64(min))
}

func decimal(v float64) float64 {
    val, _ :
= strconv.ParseFloat(fmt.Sprintf("%.3f", v), 64) return val }

 

常用的方法有:(以有種子的為例,無種子的直接通過 rand 報名呼叫對應的方法)

1> 按型別隨機類:
func (r *Rand) Int() int
func (r *Rand) Int31() int32
func (r *Rand) Int63() int64
func (r *Rand) Uint32() uint32
func (r *Rand) Float32() float32  // 返回一個取值範圍在[0.0, 1.0)的偽隨機float32值
func (r *Rand) Float64() float64  // 返回一個取值範圍在[0.0, 1.0)的偽隨機float64值

2>指定隨機範圍類:
func (r *Rand) Intn(n int) int
func (r *Rand) Int31n(n int32) int32
func (r *Rand) Int63n(n int64) int64

 

拓展:對於需要隨機指定位數的,當位數不夠是,可以通過前邊補0達到長度一致,如:

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

func main() {

  // 隨機產生4位長度偽隨機數
    for i := 0; i < 10; i++ {
        fmt.Printf("%.4d ", rand.Int31()%10000)
    }
}

// 8081 7887 1847 4059 2081 1318 4425 2540 0456 3300

二、”crypto/rand“ 包實現了用於加解密的更安全的隨機數生成器。

  該包中常用的是 func Read(b []byte) (n int, err error) 這個方法, 將隨機的byte值填充到b 陣列中,以供b使用。示例如下:

import (
    "crypto/rand"
    "fmt"
)

func main() {
    b := make([]byte, 20)
    fmt.Println(b)       //

    _, err := rand.Read(b)
    if err != nil {
        fmt.Println(err.Error())
    }

    fmt.Println(b)
}

import (
    "crypto/rand"
    "fmt"
)

func main() {
    b := make([]byte, 20)
    fmt.Println(b)       
    _, err := rand.Read(b)
    if err != nil {
        fmt.Println(err.Error())
    }

    fmt.Println(b)
}

// [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
// [82 253 252 7 33 130 101 79 22 63 95 15 154 98 29 114 149 102 199 77]