import "math/rand" func luckyCode() int32 { seed := time.Now().UnixNano() // rand內部運算的隨機數 code := rand.New(rand.NewSource(seed)).Int31n(int32(rateMax)) // rand計算得到的隨機數 return code }
此方法為偽隨機,如果隨機數種子seed相同,則得到的code也相同。
但將seed聲明全局變量,不用每次都重設隨機數種子。高並發下可以得到近似真隨機數的效果(高並發下重復幾萬次真隨機數也有重復。。。),但耗時比真隨機數低很多。如果要得到隨機字符串可以用拼接的形式盡量避免重復(比如 時間戳+隨機數),時間戳和隨機數在不太高的並發下都相同的概率應該極小吧。。。
【推薦用法】
package main import ( "fmt" "log" "math/rand" "net/http" "time" ) func myHandler(w http.ResponseWriter, r *http.Request) { num := rand.Intn(99990000) fmt.Println(num) } func main() { rand.Seed(time.Now().UnixNano()) http.HandleFunc("/", myHandler) log.Fatal(http.ListenAndServe(":8080", nil)) }
========================================================================
真隨機數
package main import ( "crypto/rand" "fmt" "math/big" "time" ) func main() { // 真隨機 start := time.Now().UnixNano() num, _ := rand.Int(rand.Reader, big.NewInt(100)) a := int(num.Int64())
fmt.Printf("真隨機數類型為:%T,值為%v", a, a) fmt.Println(time.Now().UnixNano() - start) }
結果:
真隨機數類型為:int,值為4
2991800
獲取一個100以內的int型真隨機數用了大概3ms,比較慢
package main import ( "crypto/rand" "fmt" "math/big" "strconv" "strings" ) var arr = [10]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} func main() { str := randomString(10) // 生成隨機10位數字字符串 fmt.Println(str) } func randomString(n int) string { var b []string for i := 0; i < n; i++ { num, _ := rand.Int(rand.Reader, big.NewInt(int64(len(arr)))) // 1.將 *big.Int 轉化為 int64 // 2.將 int 64 轉化為 int // 3.將 int 轉化為 string b = append(b, strconv.Itoa(arr[int(num.Int64())])) } str := strings.Join(b, "") return str }
結果:2792200018