go生成隨機數

用習慣了python裏面的random模塊,隨機數真的是順手就來,這次用到了go,沒想到生成的居然是僞隨機數,首次生成雖然隨機了,但是再次生成就一直是這個,這怎麼搞,完全沒隨機啊,下面說一說踩過的坑!!!

1. 首先來說一下什麼是隨機數

隨機數,是使用一個確定性的算法計算出來隨機數序。在程序開發中經常需要產生隨機數,如隨機數驗證碼登陸、作爲唯一身份標識數據等等。

2. go中生成隨機數的有兩個包,分別是“math/rand”和“crypto/rand”,

  • 前者實現了僞隨機數生成器,
  • 後者實現了用於加解密的跟安全的隨機數生成器,當然,性能也就降下來了,畢竟魚與熊掌不可兼得

3. 隨機數生成

func main() {
	for i:=0; i<10; i++ {
		fmt.Print(rand.Intn(10), " ")
	}
}

結果: 1 7 7 9 1 8 5 0 6 0 --> 生成的是
再來一次: 1 7 7 9 1 8 5 0 6 0 -->還是這個結果,這叫啥子隨機數,查看文檔,繼續試驗

4. 初始化隨機種子函數(下面爲官方文檔說明)

func Seed(seed int64)

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). Seed values that have the same remainder when divided by 2^31-1 generate the same pseudo-random sequence. Seed, unlike the Rand.Seed method, is safe for concurrent use.

我認爲的意思就是系統每次都會先用Seed函數初始化系統資源,如果用戶不提供seed參數,則默認用seed=1來初始化,這就是爲什麼每次都輸出一樣的值的原因,而且,Seed方法是併發安全的.
所謂種子,通俗理解可以理解爲一個抽獎的獎池,我們自定義一個獎池,從我們的獎池中進行隨機抽獎,種子就是我們獎池中的數據

5. 使用種子生成

func main() {
	// 我們一般使用系統時間的不確定性來進行初始化
	rand.Seed(time.Now().Unix())
	for i:=0; i<10; i++ {
		fmt.Print(rand.Intn(10), " ")
	}
}

或者我們可以使用rand.NewSource()

func checkSumBuilder() (string, string, string){
	r := rand.New(rand.NewSource(time.Now().UnixNano()))
	num := r.Intn(128)
}

6. Intn函數

func Intn(n int) int

生成 [0,n)區間的一個隨機數(注意:不包括n)
更多詳情查看math/rand官網

7. 生成指定位數的隨機數(以生成8位爲例)

package main
import (
   "fmt"
   "math/rand"func main() {
	s := fmt.Sprintf("%08v", rand.New(rand.NewSource(time.Now().UnixNano())).Int63n(100000000))
	fmt.Println(s)
}

8. 真隨機數

如果我們的應用對安全性要求比較高,需要使用真隨機數的話,那麼可以使用 crypto/rand 包中的方法,這樣生成的每次都是不同的隨機數.

package main
import (
 "crypto/rand"
 "fmt"
 "math/big"
)
func main() {
 // 生成 10 個 [0, 128) 範圍的真隨機數。
 for i := 0; i < 10; i++ {
  result, _ := rand.Int(rand.Reader, big.NewInt(128))
  fmt.Println(result)
 }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章