您好,登錄后才能下訂單哦!
隨機數我們都知道,就是計算機通過某種算法,“隨機”的生成一個數字。很多編程語言都有內置的方法來生成隨機數,那么 GoLang 中是怎樣一種情況呢?
偽隨機數
我們都知道“隨機數”在現實生活中的概念,可能你隨手拋一個硬幣,就可以說其結果是隨機的,但是在計算機中要確定一個“隨機數”真的是“隨機數”,那可是有標準的,不是你隨隨便便說是就是。
根據密碼學原理,要想對一個“隨機數”進行隨機性檢驗有以下幾個標準:
根據以上幾個標準,其對應的隨機數也就分為以下幾類:
了解了以上幾個概念,我們就知道了“偽隨機數”其實就是一個“看似隨機,實則并不真正隨機”的數字。
偽隨機數生成器
在實際應用中大部分情況下偽隨機數就足夠了。這些數列是“似乎”隨機的數,實際上它們是通過一個固定的、可以重復的計算方法產生的。因為它們實際上是可以計算出來的,所以它們并不真正地隨機,但是它們具有類似于隨機數的統計特征。產生這樣的結果的生成器我們叫做偽隨機數生成器。
一般只有在密碼學場景中,我們才需要使用“真隨機數”。
在大部分編程語言中,提供的都是“偽隨機數生成器”,例如 JS 中的 Math.random() , GoLang 中的 math/rand 包。
GoLang 中的偽隨機數
在 GoLang 中,我們可以通過 math/rand 包里的方法來生成一個偽隨機數:
package main import ( "fmt" "math/rand" ) func main() { fmt.Println(rand.Int()) // => 134020434 }
上面的代碼中,我們通過 rand.Int() 方法來生成一個偽隨機數。看起來好像沒什么問題嘛,人家也很 OK 啦。
但是細心的你會發現,你在自己電腦上運行上面的代碼竟然和我的一樣。無論你怎么運行,它都一樣。
我們知道 JS 中的 Math.random() 每次都會返回一個不一樣的數字,但是 GoLang 中的偽隨機數生成器默認情況下竟然會返回相同的數值,這還不反了天了?
都是偽隨機數生成器,為什么差別就這么大呢?這里我們就要了解一下“隨機種子”的概念啦。
隨機種子
我們知道,偽隨機數,是使用一個確定性的算法計算出來的似乎是隨機的數序,因此偽隨機數實際上并不隨機。
那么自然,在計算偽隨機數時假如使用的開始值不變的話,那么算法計算出的偽隨機數的數序自然也是不變的咯。
這個“開始值”,就被稱為隨機種子。
查閱文檔,我們得知, Int() 函數是從 default Source (默認源)中產生的偽隨機數。
而這個 default Source ,我們從Seed 部分可以看到,如果你沒有設置隨機種子,那么默認初始種子總是從 1 開始。
既然隨機種子一樣,那自然其結果也是一樣的。
隨機的偽隨機數
我們已經知道了默認隨機種子是從 1 開始,那么我們只要在每次生成隨機數之前先設置一個不一樣的種子,那么其結果自然也就不一樣了。
我們要盡可能保證每次偽隨機數生成器工作時使用的是不同的種子,通常的做法是采用當前時間作為種子。
package main import ( "fmt" "math/rand" "time" ) func main() { rand.Seed(int64(time.Now().UnixNano())) fmt.Println(rand.Int()) }
這樣,由于種子不同,我們每次運行的結果也就不一樣。我們就能達到獲取偽隨機數的目的啦。
真隨機數
如果我們的應用對安全性要求比較高,需要使用真隨機數的話,那么可以使用 crypto/rand 包中的方法。
package main import ( "crypto/rand" "fmt" "math/big" ) func main() { // 生成 20 個 [0, 100) 范圍的真隨機數。 for i := 0; i < 20; i++ { result, _ := rand.Int(rand.Reader, big.NewInt(100)) fmt.Println(result) } }
上面的程序每次運行的結果都是不一樣的,會真正隨機的生成隨機數。
訪問:https://github.com/sqrthree/sqrthree.github.io/issues
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。