go math/rand包详解
go math/rand
package rand
import "math/rand"
rand包实现了伪随机数生成器。
随机数从资源生成。包水平的函数都使用的默认的公共资源。该资源会在程序每次运行时都产生确定的序列。如果需要每次运行产生不同的序列,应使用Seed函数进行初始化。默认资源可以安全的用于多go线程并发。
在go中生成随机数需要一个结构体实例 Rand ,要构建这个结构体需要一些参数;为了便捷,go已经在math/rand包中定义好了一个Rand结构体实例,只需要调用Rand的一些方法就可以生成各种随机数来。下面简单认识一下Rand结构体:
type Rand struct {
src Source
s64 Source64 // 如果src为空,则为64
// readVal包含用于字节的63位整数的remainer,在最近的读取调用期间生成。
// 它被保存,以便下一个读调用可以从上一个读调用结束的地方开始。
readVal int64
// readPos表示仍然有效的readVal的低位字节数。
readPos int8
}
简单示例:
package main
import (
"fmt"
"math/rand"
)
func main() {
// 调用rand的方法生成伪随机int值
fmt.Println(rand.Int())
fmt.Println(rand.Int31())
fmt.Println(rand.Intn(5))
}
运行结果:
5577006791947779410
2019727887
2
当代码运行多次发现时,结果都是一样的。不管怎么运行代码,产生的结果都是这三个数,不会变。为什么?这是因为我们还没有设置随机数种子。
rand.Seed 设置随机数种子
func (r *Rand) Seed(seed int64) 使用给定的seed来初始化生成器到一个确定的状态。
修改后的代码:
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
rand.Seed(time.Now().UnixNano()) // 取纳秒时间戳,可以保证每次的随机数种子都不同
fmt.Println(rand.Int())
fmt.Println(rand.Int31())
fmt.Println(rand.Intn(5))
}
代码多次运行,就会发现每次结果是不一样的
7684945739848266880
1210528256
4
-------------------
4700552700982711365
1927716820
4
自定义生成Rand结构体,设置随机数种子
除了上面生成伪随机数的方法,我们还可以自定义生成Rand结构体,本质上与Rand提供好的结构体没有太大区别,下面简单介绍下自己声明Rand结构体,来生成伪随机数:
func NewSource(seed int64) Source
使用给定的种子创建一个伪随机资源。
func New(src Source) *Rand
返回一个使用src生产的随机数来生成其他各种分布的随机数值的*Rand。
代码示例:
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
source := rand.NewSource(time.Now().UnixNano()) // 使用当前的纳秒生成一个随机源,也就是随机种子
ran := rand.New(source) // 生成一个rand
fmt.Println(rand.Int())
fmt.Println(rand.Int31())
fmt.Println(rand.Intn(5))
}
这两种方法本质上没有区别,NewSource()方法等价于前面的rand.Seed()方法,都是用来设置随机种子。
其它生成随机数的方法
Rand生成随机数当然不只这三个方法,还有其它生成随机数的方法
func (r *Rand) Int63() int64
返回一个int64类型的非负的63位伪随机数。
func (r *Rand) Uint32() uint32
返回一个uint32类型的非负的32位伪随机数。
func Int31n(n int32) int32
返回一个取值范围在[0,n)的伪随机int32值,如果n<=0会panic。
func Int63n(n int64) int64
返回一个取值范围在[0, n)的伪随机int64值,如果n<=0会panic。
func (r *Rand) Float32() float32
返回一个取值范围在[0.0, 1.0)的伪随机float32值。
func (r *Rand) Float64() float64
返回一个取值范围在[0.0, 1.0)的伪随机float64值。
func (r *Rand) Perm(n int) []int
返回一个有n个元素的,[0,n)范围内整数的伪随机排列的切片。
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() {
for i := 0; i < 10; i++ {
fmt.Printf("%.4d ", rand.Int31()%10000)
}
}
运行结果:
8081 7887 1847 4059 2081 1318 4425 2540 0456 3300
go crypto/rand
package rand
import "crypto/rand"
rand包实现了用于加解密的更安全的随机数生成器,主要应用场景:生成随机加密串
主要方法
(1)func Int(rand io.Reader, max *big.Int) (n *big.Int, err error)
返回一个在[0, max)区间服从均匀分布的随机值,如果max<=0则会panic
(2)func Prime(rand io.Reader, bits int) (p *big.Int, err error)
返回一个具有指定字位数(二进制的位数)的数字,该数字具有很高可能性是质数。如果从rand读取时出错,或者bits<2会返回错误
(3)func Read(b []byte) (n int, err error)
本函数是一个使用io.ReadFull调用Reader.Read的辅助性函数。当且仅当err == nil时,返回值n == len(b)
代码示例:
package main
import (
"crypto/rand"
"encoding/base64"
"fmt"
"math/big"
)
func main() {
//1、Int
n, err := rand.Int(rand.Reader, big.NewInt(128))
if err == nil {
fmt.Println("rand.Int:", n, n.BitLen())
}
//2、Prime
p, err := rand.Prime(rand.Reader, 5)
if err == nil {
fmt.Println("rand.Prime:", p)
}
//3、Read
b := make([]byte, 32)
m, err := rand.Read(b)
if err == nil {
fmt.Println("rand.Read:", b[:m])
fmt.Println("rand.Read:", base64.URLEncoding.EncodeToString(b))
}
}
运行结果:
rand.Int: 92 7
rand.Prime: 29
rand.Read: [207 47 241 208 190 84 109 134 86 106 87 223 111 113 203 155 44 118 71 20 186 62 66 130 244 98 97 184 8 179 6 230]
rand.Read: zy_x0L5UbYZWalffb3HLmyx2RxS6PkKC9GJhuAizBuY=
常用的是 func Read(b []byte) (n int, err error) 这个方法, 将随机的byte值填充到b 数组中,以供b使用。示例如下:
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)
}
运行结果:
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
[68 221 145 73 115 224 13 110 218 130 19 139 38 170 145 58 251 188 126 197]
go math/rand包详解的更多相关文章
- 常见 jar包详解
常见 jar包详解 jar包 用途 axis.jar SOAP引擎包 commons-discovery-0.2.jar 用来发现.查找和实现可插入式接口,提供一些一般类实例化.单件的生命周期 ...
- Java.lang 包 util 包等各个包详解
java.lang 该包提供了 Java 编程的基础类,例如 Object.Math.String.StringBuffer.System.Thread 等,不使用该包就很难编写 Java 代码了. ...
- Spring jar包详解
Spring jar包详解 org.springframework.aop ——Spring的面向切面编程,提供AOP(面向切面编程)的实现 org.springframework.asm——spri ...
- Spring——jar包详解(转)
Spring——jar包详解 org.springframework.aop ——Spring的面向切面编程,提供AOP(面向切面编程)的实现 org.springframework.asm——spr ...
- Spring 3.x jar 包详解 与 依赖关系
以下的内容我会持续更新(当然是我有新发现的时候); 以下内容是我在网上搜索.整理.修改的而成的内容.由于很多内容都是转载了,无法追溯到源头,因此无法一一对原作者进行道谢. 这几天,我查阅大量的官方的文 ...
- Spring 3.x jar 包详解 与 依赖关系(转)
以下的内容我会持续更新(当然是我有新发现的时候); 以下内容是我在网上搜索.整理.修改的而成的内容.由于很多内容都是转载了,无法追溯到源头,因此无法一一对原作者进行道谢. 这几天,我查阅大量的官方的文 ...
- 2.TCP_IP互联线缆_TCP_UDP报文抓包详解
TCP_IP互联线缆_TCP_UDP报文抓包详解 2.1网线标准 直通线 交叉线 异种设备互联使用直通线 同种设备互联使用交叉线 TCP和UDP 端口寻址 TCP数据格式 TCP三次握手 UDP数据格 ...
- TCP通讯处理粘包详解
TCP通讯处理粘包详解 一般所谓的TCP粘包是在一次接收数据不能完全地体现一个完整的消息数据.TCP通讯为何存在粘包呢?主要原因是TCP是以流的方式来处理数据,再加上网络上MTU的往往小于在应用处理的 ...
- easyui下载包详解
easyui包详解: 文件夹: demo--该目录下存放的是 EasyUI PC 版各插件的示例示例.如果不想在官网上查看演示,可以在该目录下找到相应的演示示例 demo-mobile--该目录下存放 ...
- spring原理案例-基本项目搭建 02 spring jar包详解 spring jar包的用途
Spring4 Jar包详解 SpringJava Spring AOP: Spring的面向切面编程,提供AOP(面向切面编程)的实现 Spring Aspects: Spring提供的对Aspec ...
随机推荐
- Qt编写雷达模拟仿真工具(模拟点/歼击机/航母/发射导弹/爆炸效果/激光雷达等)
一.简单介绍 雷达模拟仿真工具,主要通过模拟点模拟相关物体,方位.航向角.距离.速度,并且显示相关详情信息可建立跟踪线建立与模拟点联系.可自定义更换模拟点背景达到更加逼真效果,如歼击机,航母发射导弹效 ...
- Qt编写可视化大屏电子看板系统19-横向柱状图
一.前言 横向柱状图的绘制这玩意当初还着实花费了一些时间,因为从v1版本开始,默认XY坐标轴是没有交换位置的处理的,也只有垂直的柱状图,要想换成横向的柱状图必须是自己拿到数据重新绘制,数据值的设置一般 ...
- 15条 Karpenter 最佳实践,轻松掌握弹性伸缩
Karpenter 是一款高性能.灵活的开源 Kubernetes 集群自动扩展工具,目前已支持 AWS 和阿里云.它可以根据不断变化的应用负载,快速启动大小合适的计算资源,进而提升应用的可用性. 相 ...
- Java子线程无法获取Attributes的解决方法
在Java多线程编程中,开发者经常会遇到子线程无法获取主线程设置的Attributes的问题.Attributes通常用于存储与当前线程相关的数据,尤其在Web应用中,它们常用于请求上下文的管理.然而 ...
- Spring Cloud Alibaba实战,从微服务架构到基本服务配置
https://blog.csdn.net/itcast_cn/article/details/124558887 Spring Cloud Alibaba 实战 1目标理解什么是微服务架构理解什么是 ...
- SSL和HTTPS
转载: 链接 随着互联网的发展,给我们的生活带来便利的同时,也伴随着很多网络钓鱼.信息泄露.网络诈骗等事件的频繁发生,企业网站被钓鱼网站仿冒,遭受经济损失,影响品牌形象. 如果网站不使用SSL证书,数 ...
- nginx basic验证
打开个生成htpasswd的网站 输入信息生成结果 将结果保存到nginx一个文件里面 修改nginx的conf文件 auth_basic "webA"; #这个"&qu ...
- FastReport实现遍历Dataset数据集计算
delphi在使用fastreport进行打印时,需要对数据进行计算求和. 在打印文本框的OnBeforePrint事件中进行以下代码即可实现效果 procedure Memo7OnBeforePri ...
- 深入理解Mybatis分库分表执行原理
前言 工作多年,分库分表的场景也见到不少了,但是我仍然对其原理一知半解.趁着放假前时间比较富裕,我想要解答三个问题: 为什么mybatis的mapper.xml文件里的sql不需要拼接表名中的分表? ...
- Nmap 脚本使用
Nmap 脚本使用 使用 Nmap 脚本是扩展 Nmap 功能的一种高效方式,允许用户执行从简单的服务检测到复杂的漏洞利用的各种任务.通过指定 --script 选项,并结合相应的脚本名称或类型,用户 ...