golang之真伪随机数


伪随机数

import (
	"math/rand"
	"fmt"
)

func main(){
	rand.Seed(1)
	fmt.Println(rand.Intn(20))
	fmt.Println(rand.Intn(20))
	fmt.Println(rand.Intn(20))
}

将该程序运行多次,每次打印的随机数都是:1,7,7, 该随机数与seed有关

真随机数

import (
	"math/big"
	"crypto/rand"
	"fmt"
)

func main(){
	a, _ := rand.Int(rand.Reader, big.NewInt(255))
	b, _ := rand.Int(rand.Reader, big.NewInt(255))
	c, _ := rand.Int(rand.Reader, big.NewInt(255))
	d, _ := rand.Int(rand.Reader, big.NewInt(255))
	fmt.Println(a)
	fmt.Println(b)
	fmt.Println(c)
	fmt.Println(d)
}

这个是真正的随机数,每次都是随机

伪随机数导致的问题

场景:开了一个http服务,随机生成ip地址,代码如下

import (
	"encoding/json"
	"net/http"
	"math/rand"
	"time"
	"fmt"
)

func main(){
	http.HandleFunc("/job", func(writer http.ResponseWriter, request *http.Request) {
		rand.Seed(time.Now().Unix())
		ip := fmt.Sprintf("%d.%d.%d.%d", rand.Intn(255), rand.Intn(255), rand.Intn(255), rand.Intn(255))
		result := make(map[string]string)
		result["data"] = ip
		b,_ := json.Marshal(result)
		writer.Write(b)
	})
	err := http.ListenAndServe(":28888", nil)
	if err !=nil {
		panic(err)
	}
}

客户端开启多线程,请求服务端的随机ip地址,代码:

import (
	"net/http"
	"io/ioutil"
	"fmt"
	"time"
)

func main() {
	pool := make(chan struct{}, 5)
	for ; ;  {
		pool <- struct{}{}
		go func(c chan struct{}) {
			defer func() {
				<- c
			}()
			resp,err := http.Get("http://127.0.0.1:28888/job")
			if err != nil {
				fmt.Println(err)
			}
			if resp != nil {
				if resp.Body != nil {
					defer func() {
						resp.Body.Close()
					}()
				}
			}
			body,err := ioutil.ReadAll(resp.Body)
			if err != nil {
				fmt.Println(err)
			}
			fmt.Println(string(body))
			time.Sleep(time.Second)
		}(pool)
	}
	select {}
}

打印之后发现,每次5个协程请求的ip地址是一模一样的
原因:多协程同时请求http服务,获取ip地址的时候,rand.Seed(time.Now().Unix())设置的随机数种子一样,生成的随机数也是一样的,最后ip就重复了
解决办法:把伪随机数换成真随机数

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值