1、math/rand

随机数从资源生成。包水平的函数都使用的默认的公共资源。

该资源会在程序每次运行时都产生确定的序列。如果需要每次运行产生不同的序列,应使用Seed函数进行初始化。默认资源可以安全的用于多go程并发。

关于种子seed
程序启动的时候,种子的初始值是一样的,也就是说随机数是一样的,什么意思呢?

package mainimport ("fmt""math/rand"
)func main(){data := rand.Int63n(100)fmt.Println(data)
}

每次运行go run main.go
打印的都是 10

如果我们播放种子

package mainimport ("fmt""math/rand""time"
)func main(){rand.Seed(time.Now().Unix()) // unix 时间戳,秒data := rand.Int63n(100)fmt.Println(data)
}

这样每次执行go run main.go
打印的结果就不一样,但是,根据随机数的特性,如果两次执行的时间戳是在同一秒,那么打印的结果是相同的。
以上的随机数相同的情况是发生在程序启动的时候,如果程序启动后,每次生成随机数会怎样呢?

package mainimport ("fmt""math/rand"
)func main(){for i := 0; i<5; i++ {data := rand.Int63n(100)fmt.Println(data)}
}

运行 go run main.go
打印
10
51
21
51
37

再次运行 go run main.go
打印
10
51
21
51
37

可见每次启动的结果是一样的;但是程序启动后,每次的随机数都不尽相同,是随机的。

如果再加上种子呢?

package mainimport ("fmt""math/rand""time"
)func main(){for i := 0; i<5; i++ {rand.Seed(time.Now().Unix()) // unix 时间戳,秒data := rand.Int63n(100)fmt.Println(data)}
}

运行 go run main.go
打印
86
86
86
86
86

再次运行 go run main.go
打印
72
72
72
72
72

每次启动程序,因为种子不一样,所以随机数不一样;但是程序启动后,每次也都是播放种子,秒级时间戳,如果时间戳一样,就导致种子一样,生成的随机数就一样,所以五次的随机数是一样的。

通过上面的例子。可以知道,播放种子不是必须的,除非要求每次启动程序的时候随机数不一样。

并且,要设置种子的情况下,应该放在整个程序启动的时候,而且只需要设置一次即可。修改上面的例子:

package mainimport ("fmt""math/rand""time"
)func main(){rand.Seed(time.Now().UnixNano()) // 纳秒时间戳for i := 0; i<5; i++ {data := rand.Int63n(100)fmt.Println(data)}
}

运行 go run main.go
打印
3
49
46
83
25

再次运行 go run main.go
打印
39
3
14
42
65

这次就是理想的结果了。使用纳秒时间戳基本就没问题了,因为我们的程序几乎不会在1纳秒时间内多次启动的。

下面来讲讲rand包的具体用法

rand 包提供了两块的内容,一块是基于 Rand 结构体及其方法;另一块是基于 Rand 结构体再封装的可直接调用的方法 rand.xxx,查看源码就知道它们是同样的功能。

所以,生成随机数有两种方式

rander := rand.New(rand.NewSource(time.Now().UnixNano()))
n1 := rander.Intn(100)rand.Seed(time.Now().UnixNano())
n2 := rand.Intn(100)

使用第一种方法,将 rander 作为包的全局变量,这样就只会设置一次种子。

var Rander = rand.New(rand.NewSource(time.Now().UnixNano()))

随机整数

func (r *Rand) Int() int
func (r *Rand) Int31() int32
func (r *Rand) Int63() int64
func (r *Rand) Uint32() uint32
func (r *Rand) Uint64() uint64
func (r *Rand) Intn(n int) int
func (r *Rand) Int31n(n int32) int32
func (r *Rand) Int63n(n int64) int64

Int, Int31, Int63 生成的数都太大,一般使用 Intn, Int31n, Int63n。得到的范围 [0, n),想要得到 [0, n],就要使用 Intn(n + 1),想要得到 [10, 100] 的随机数,就要使用 Intn(91) + 10。

随机浮点数

func (r *Rand) Float32() float32
func (r *Rand) Float64() float64

得到 [0, 1) 之间的浮点数,32单精度,64双精度。

基于正态分布的随机浮点数

func (r *Rand) NormFloat64() float64

基于指数分布的随机浮点数

func (r *Rand) ExpFloat64() float64

随机序列

func (r *Rand) Perm(n int) []int

返回一个有n个元素的,[0,n)范围内整数的伪随机排列的切片。

Rander.Perm(10) // [1 8 0 4 7 6 3 2 9 5]

总结:

package mainimport ("fmt""math/rand""strings""time"
)func main() {s := RandString(10)fmt.Println(s)
}var Rander = rand.New(rand.NewSource(time.Now().UnixNano()))const letterString = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
const numLetterString = "0123456789"// 随机生成字符串
func RandStr(n int, letter string) string {str := []byte(letter)res := ""for i := 0; i < n; i++ {res += fmt.Sprintf("%c", str[Rander.Intn(strings.Count(letter, "") - 1)])}return res
}func RandNumStr(n int) string {return RandStr(n, numLetterString)
}func RandString(n int) string {return RandStr(n, letterString)
}func RandOrder(n int) string {return time.Now().Format("20060102150405") + RandNumStr(n)
}// 包含min, max
func RandNum(min , max int) int {return Rander.Intn(max - min + 1) + min
}

2、crypto/rand

实现了用于加解密的更安全的随机数生成器。

变量 var Reader io.Reader
是一个全局、共享的密码用强随机生成器。在Unix类型系统中,会从/dev/urandom读取;而windows中会调用RtlGenRandom API。

提供的方法
1、返回一个基于[0, max)的随机数

// Int returns a uniform random value in [0, max). It panics if max <= 0.
func Int(rand io.Reader, max *big.Int) (n *big.Int, err error)

示例

r, err := rand.Int(rand.Reader, big.NewInt(100))
fmt.Println(r.Int64(), err)

2、根据指定的位数bits,返回一个数,大概率是素数,(不知道这个函数是干嘛用的)

// Prime returns a number, p, of the given size, such that p is prime
// with high probability.
// Prime will return error for any error returned by rand.Read or if bits < 2.
func Prime(rand io.Reader, bits int) (p *big.Int, err error)

示例

p, err := rand.Prime(rand.Reader, 8)
fmt.Println(p.Int64(), err)

8个二进制位的最大值为255,此处会随机返回小于255的素数。

3、生成随机的二进制序列

// Read is a helper function that calls Reader.Read using io.ReadFull.
// On return, n == len(b) if and only if err == nil.
func Read(b []byte) (n int, err error) {return io.ReadFull(Reader, b)
}

比如,随机生成16个字节的数据

var b [16]byte
n, err := rand.Read(b[:])
fmt.Println(n, err)
fmt.Println(b)返回值
16 <nil>
[94 184 113 36 224 18 239 52 69 242 14 84 174 113 125 15]

我们可以将其转换成16进制数,也就是32位

buf := make([]byte, 32)
hex.Encode(buf, b[:])
fmt.Println(string(buf))得到
5eb87124e012ef3445f20e54ae717d0f

通过这个方法可以生成随机的字符串。

golang中的随机数rand相关推荐

  1. c语言随机字符rand,C语言中生产随机数 rand()函数

    一:如果你只要产生随机数而不需要设定范围的话,你只要用rand()就可以了:rand()会返回一随机数值, 范围在0至RAND_MAX 间.RAND_MAX定义在stdlib.h, 其值为214748 ...

  2. golang中的随机数

    随机数 种子一样,每次运行程序产生的随机数一样 import ("fmt""math/rand" )func main() {rand.Seed(666)for ...

  3. 一文详解编程中的随机数

    一文详解编程中的随机数 随机数的类型 真随机数生成器 TRNG - True Random Number Generator 伪随机数生成器 PRNG - Pseudo Random Number G ...

  4. golang中的读写锁

    简介 互斥锁本质是当一个协程访问的时候,其他协程都不能访问. 其实主要是想:修改数据要同步,这样其他协程才可以感知到,所以真正的互斥应该是读取和修改,修改和修改之间,读和读是没有互斥操作的必要的 读写 ...

  5. 关于C++,Java和Python中的随机数生成法

    首先我们来说说C++中的随机数生成: 我们知道在C++用函数rand()获取的是一个0 ~ RAND_MAX之间的一个随机数.其中RAND_MAX的值为32767. 首先我们来分析两个程序: #inc ...

  6. matlab产生一组均为一的矩阵,在matlab中如何从一组数中得到随机数组成一个n*n的矩阵...

    导航:网站首页 > 在matlab中如何从一组数中得到随机数组成一个n*n的矩阵 时间:2019-3-15 在matlab中如何从一组数中得到随机数组成一个n*n的矩阵 从1,2,3,4,5,6 ...

  7. c语言中二维数组中产生随机数,C语言中是如何进行随机数生成的[多图]

    C语言中是如何进行随机数生成的.C语言是编程人员经常会到的一款计算机编程语言,有的朋友想知道怎样使用C语言进行随机数生成,那么就快随小编一起来看看这篇C语言中是如何进行随机数生成的吧!其中不仅为大家介 ...

  8. 算法竞赛中的随机数产生和断言

    算法竞赛中的随机数产生和断言 #include <algorithm> #include <vector> #include <cstdlib> #include ...

  9. java如何实取随机数_java - 如何在Kotlin中获取随机数?

    java - 如何在Kotlin中获取随机数? 可以在2个参数之间返回随机整数的通用方法,如ruby,可以使用rand(0..n). 有什么建议吗? 16个解决方案 208 votes 我的建议是In ...

最新文章

  1. 局部加权线性回归(Local Weighted Linear Regression)+局部加权回归+局部线性回归
  2. 【面试 struts2】【第三篇】struts2的问题
  3. 流程图绘制技巧及实战案例
  4. 2021云栖大会,打卡IoT最全攻略
  5. sys.argv和getopt
  6. 分类学计算机面试什么,史上最全的机器学习面试题-机器学习爱好者必看
  7. 快速从mysqldump文件中恢复一个表
  8. 使用matlab对路径的字符串进行分割和合成
  9. Linux 内存管理之 SLUB分配器(5):slub初始化过程
  10. 考察一名UI设计师的能力素质模型(转)
  11. js获取当前农历时间
  12. 电脑任务栏应用图标变成白色怎么恢复
  13. linux系统查看dns缓存,如何清空linux的DNS缓存
  14. 讯飞AIUI平台语义理解配置全攻略——以Android版AIUI SDK为例
  15. BookCollectionSoftware - 图书管理(知识点糅合::类,对象,抽象类,接口,封装,继承,多态,顺序表)- java - 细节狂魔
  16. 内网 centos7 离线安装rpm包的三种方法
  17. 图论(九)有向图和网络
  18. 为什么要加密所有个人身份信息(PII)
  19. css3之transform-origin属性详解图文笔记
  20. 滤镜功能针的萌翻了!Snapchat为狗狗配戴眼镜

热门文章

  1. Unity绳子插件QuickRopes使用方法(让你快速创建你想要的绳索效果)
  2. Win11校园网不弹出登录页面怎么回事?
  3. QQ浏览器HD iOS 动态化/热修复方案QBDF解释器-词法分析(3)【简书被冻结-搬运】
  4. 学习CC2541开发笔记
  5. 杀戮尖塔有android版本吗,杀戮尖塔安卓版
  6. 隐写文件的识别和解码工具——国内首款隐写术识别软件(隐译)
  7. 天猫提示您使用的浏览器版本过低的完美解决办法
  8. pxcook导出html代码,Pxcook标注工具的相关使用说明
  9. 怎么样让电脑桌面显示有计算机,怎么让电脑多屏幕显示?让电脑多屏幕显示的设置方法...
  10. lnmp一键部署安装脚本