在Golang中,有两个包提供了rand,分别为 "math/rand" 和 "crypto/rand",  对应两种应用场景。

  • "math/rand" 包实现了伪随机数生成器。也就是生成 整形和浮点型。 该包中根据生成伪随机数是是否有种子(可以理解为初始化伪随机数),可以分为两类:

    • 有种子。通常以时钟,输入输出等特殊节点作为参数,初始化。该类型生成的随机数相比无种子时重复概率较低。
    • 无种子。可以理解为此时种子为1, Seek(1)

golang 随机数有一个很有趣的地方,如果我们不自行定义随机数种子的话,每次生成的随机数都是一样的。golang 在默认随机的时候,固定以数字 1 作为种子。既然种子都固定了的话,那每次执行的结果当然是一样的。比如 第二个for 循环,打印 10 个随机数,每次运行结果是一模一样的。 

要解决这个问题,就需要以时间作为随机数种子。如第一个for循环:

package main

import (
"fmt"
"math/rand"
"time"
) func main() {
      //以时间为随机种子
for i := 0; i < 10; i++
r := rand.New(rand.NewSource(time.Now().UnixNano()))
fmt.Printf("%d ", r.Int31())
} fmt.Println(" ")
    //无种子,其实是固定以1为种子
for i := 0; i < 10; i++ {
fmt.Printf("%d ", rand.Int31())
}
}

  输出:

第一次运行结果

276310213 276310213 276310213 939632684 939632684 939632684 939632684 939632684 939632684 939632684

1298498081 2019727887 1427131847 939984059 911902081 1474941318 140954425 336122540 208240456 646203300

第二次运行结果

1101837366 1101837366 1101837366 1101837366 1101837366 1101837366 1101837366 1101837366 1101837366 1101837366

1298498081 2019727887 1427131847 939984059 911902081 1474941318 140954425 336122540 208240456 646203300

第三次运行结果

483465292 483465292 483465292 483465292 1406725908 1406725908 1406725908 1406725908 1406725908 1406725908

1298498081 2019727887 1427131847 939984059 911902081 1474941318 140954425 336122540 208240456 646203300

 

常用的方法有:(以有种子的为例,无种子的直接通过 rand 调用对应的方法)

1> 按类型随机类:
func (r *Rand) Int() int
func (r *Rand) Int31() int32
func (r *Rand) Int63() int64
func (r *Rand) Uint32() uint32
func (r *Rand) Float32() float32 // 返回一个取值范围在[0.0, 1.0)的伪随机float32值
func (r *Rand) Float64() float64 // 返回一个取值范围在[0.0, 1.0)的伪随机float64值 2>指定随机范围类:
func (r *Rand) Intn(n int) int
func (r *Rand) Int31n(n int32) int32
func (r *Rand) Int63n(n int64) int64

 

拓展:对于需要随机指定位数的,当位数不够是,可以通过前边补0达到长度一致,如

package main
import (
"fmt"
"math/rand"
)
func main() {
// 随机产生6位长度伪随机数
for i := 0; i < 10; i++ {
fmt.Printf("%.6d ", rand.Int31()%1000000)
}
}

  输出

498081 727887 131847 984059 902081 941318 954425 122540 240456 203300

 

package main
import (
"fmt"
"math/rand"
"time"
)
func init() {
//以时间作为初始化种子
rand.Seed(time.Now().UnixNano())
}
func main() {
a := rand.Int()
fmt.Println(a)
b := rand.Intn(100)
fmt.Println(b)
c := rand.Float32()
fmt.Println(c)
}

  输出:

1910927962
45
0.9863281

  

”crypto/rand“ 包实现了用于加解密的更安全的随机数生成器:该包中常用的是 func Read(b []byte) (n int, err error) 这个方法, 将随机的byte值填充到b 数组中,以供b使用。示例如下:

package main

import (
"crypto/rand"
"fmt"
) func main() {
b := make([]byte, 20)
fmt.Println(b) // _, err := rand.Read(b)
if err != nil {
fmt.Println(err.Error())
} fmt.Println(b)
}

几点注意项:

1、如果不使用rand.Seed(seed int64),每次运行,得到的随机数会一样,程序不停止,一直获取的随机数是不一样的;

2、每次运行时rand.Seed(seed int64),seed的值要不一样,这样生成的随机数才会和上次运行时生成的随机数不一样;

3、rand.Intn(n int)得到的随机数int i,0 <= i < n。

  

最新文章

  1. Android界面刷新之invalidate与postInvalidate的区别
  2. redis配置认证密码
  3. MINE
  4. trunc sysdate
  5. Agent admitted failure to sign using the key
  6. springMVC+jpa配置之简单案例
  7. 虚拟专用网络VPN
  8. R command
  9. Hibernate从入门到精通(三)Hibernate配置文件
  10. 近5年133个Java面试问题列表
  11. Spring声明式事务(xml配置事务方式)
  12. iOS架构设计-URL缓存
  13. [LeetCode] Minimum Absolute Difference in BST 二叉搜索树的最小绝对差
  14. JGUI源码:从头开始,建一个自己的UI框架(1)
  15. (排序的新方法)nyoj1080-年龄排序
  16. cei()、linspace()、arrange()、full()、eye()、empty()、random()
  17. maven配置jdk1.8环境
  18. 知物由学 | AI在Facebook清理有害内容上扮演了什么角色?
  19. 【两分钟视频教程】如何使用myeclipse在mac本机运行iOS配套的服务器
  20. php中++i 与 i++ 的区分详解

热门文章

  1. Git 合并单个文件
  2. Centos7 安装 zabbix 4.0
  3. LCA最近公共祖先-- HDU 2586
  4. Visual Studio的UTF-8问题
  5. github配置密钥
  6. Eclipse中Git操作(七)
  7. maven介绍(一)
  8. zz深度学习目标检测2014至201901综述
  9. 7.Vue的计算属性
  10. 数据库的查——select的基本使用