一、隨機數的概念
隨機數是計算機中常使用的一種數值,它的產生具有不可預知性。隨機數廣泛應用於加密、模擬和統計學等領域。在Go語言中,隨機數可以用math/rand包實現,利用各種方法使隨機性進一步增強。
二、偽隨機數生成器PRNG
在Go語言中,math/rand包提供了偽隨機數生成器的函數,其中最常用的就是Intn(n)函數,可以產生一個[0,n)的偽隨機整數。PRNG以種子值作為初始值,根據數學公式計算不同的隨機數。由於具有確定性,所以稱為偽隨機數。
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
rand.Seed(time.Now().UnixNano())
fmt.Println(rand.Intn(10))
}
運行上述代碼,輸出的結果是0~9的偽隨機整數,由於使用了UnixNano()將納秒級別的時間戳作為種子值,保證每次生成的隨機數都不同。可以通過Seed()函數手動設置種子值。
三、真隨機數生成器
相較於偽隨機數,真隨機數是真正的隨機數,能夠保證具有不可預知性。Go語言中提供了crypto/rand包,可以用於生成真隨機數。
package main
import (
"crypto/rand"
"fmt"
"math/big"
)
func main() {
n, err := rand.Int(rand.Reader, big.NewInt(100))
if err != nil {
fmt.Println("出錯了")
}
fmt.Println(n)
}
運行上述代碼,將產生一個範圍在0~99的真隨機整數。在生成真隨機數時,必須指定特定的種子值,這裡使用了cryptographic random generator實現安全產生真隨機數。
四、使用多個goroutine
在並行計算中,需要產生多個隨機數,每個goroutine都需要產生不同的隨機數,可以使用rand.New()函數為每個goroutine創建一個獨立種子的PRNG。
package main
import (
"fmt"
"math/rand"
"sync"
"time"
)
func worker(id int, wg *sync.WaitGroup) {
defer wg.Done()
r := rand.New(rand.NewSource(time.Now().UnixNano()))
for i := 0; i < 5; i++ {
fmt.Printf("Worker %d: %d\n", id, r.Intn(100))
time.Sleep(time.Millisecond * 100)
}
}
func main() {
var wg sync.WaitGroup
for i := 0; i < 5; i++ {
wg.Add(1)
go worker(i, &wg)
}
wg.Wait()
}
運行上述代碼,會輸出5個goroutine生成的隨機數。這裡每個goroutine都使用了一個獨立的PRNG,因此產生的隨機數的序列會不同。
五、結合時間的使用
在Go語言中,可以將時間結合到隨機數產生中,可以根據時間戳計算出不同的種子值,並將其用作PRNG的初始值。
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
rand.Seed(time.Now().UnixNano())
for i := 0; i < 5; i++ {
fmt.Println(rand.Intn(100))
time.Sleep(time.Millisecond * 100)
}
}
運行上述代碼,每隔100毫秒將會產生一個0~99範圍內的隨機數。這裡使用UnixNano()函數產生納秒級別的時間戳,作為種子值,每次運行程序將產生不同的隨機數序列。
六、總結
Go語言中提供了math/rand和crypto/rand包,分別用於產生偽隨機數和真隨機數。在多個goroutine環境下,可以為每個goroutine創建獨立的PRNG來產生隨機數。時間也可以結合隨機數產生中,利用時間戳產生不同的種子值,進一步增強隨機數生成的隨機性。
原創文章,作者:RRFDZ,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/363865.html