GoLang 中的随机数的示例代码
作者:根号三 发布时间:2024-04-26 17:16:51
随机数我们都知道,就是计算机通过某种算法,“随机”的生成一个数字。很多编程语言都有内置的方法来生成随机数,那么 GoLang 中是怎样一种情况呢?
伪随机数
我们都知道“随机数”在现实生活中的概念,可能你随手抛一个硬币,就可以说其结果是随机的,但是在计算机中要确定一个“随机数”真的是“随机数”,那可是有标准的,不是你随随便便说是就是。
根据密码学原理,要想对一个“随机数”进行随机性检验有以下几个标准:
统计学伪随机性 - 在给定的随机比特流样本中,1 的数量大致等于 0 的数量,也就是说,“10”“01”“00”“11” 四者数量大致相等。说人话就是:“一眼看上去是随机的”。
密码学安全伪随机性 - 就是给定随机样本的一部分和随机算法,不能有效的演算出随机样本的剩余部分。
真随机性 - 其定义为随机样本不可重现。
根据以上几个标准,其对应的随机数也就分为以下几类:
伪随机数 - 满足第一个条件的随机数。
密码学安全的伪随机数 - 同时满足前两个条件的随机数。可以通过密码学安全伪随机数生成器计算得出。
真随机数 -同时满足三个条件的随机数。
了解了以上几个概念,我们就知道了“伪随机数”其实就是一个“看似随机,实则并不真正随机”的数字。
伪随机数生成器
在实际应用中大部分情况下伪随机数就足够了。这些数列是“似乎”随机的数,实际上它们是通过一个固定的、可以重复的计算方法产生的。因为它们实际上是可以计算出来的,所以它们并不真正地随机,但是它们具有类似于随机数的统计特征。产生这样的结果的生成器我们叫做伪随机数生成器。
一般只有在密码学场景中,我们才需要使用“真随机数”。
在大部分编程语言中,提供的都是“伪随机数生成器”,例如 JS 中的 Math.random() , GoLang 中的 math/rand 包。
GoLang 中的伪随机数
在 GoLang 中,我们可以通过 math/rand 包里的方法来生成一个伪随机数:
package main
import (
"fmt"
"math/rand"
)
func main() {
fmt.Println(rand.Int()) // => 134020434
}
上面的代码中,我们通过 rand.Int() 方法来生成一个伪随机数。看起来好像没什么问题嘛,人家也很 OK 啦。
但是细心的你会发现,你在自己电脑上运行上面的代码竟然和我的一样。无论你怎么运行,它都一样。
我们知道 JS 中的 Math.random() 每次都会返回一个不一样的数字,但是 GoLang 中的伪随机数生成器默认情况下竟然会返回相同的数值,这还不反了天了?
都是伪随机数生成器,为什么差别就这么大呢?这里我们就要了解一下“随机种子”的概念啦。
随机种子
我们知道,伪随机数,是使用一个确定性的算法计算出来的似乎是随机的数序,因此伪随机数实际上并不随机。
那么自然,在计算伪随机数时假如使用的开始值不变的话,那么算法计算出的伪随机数的数序自然也是不变的咯。
这个“开始值”,就被称为随机种子。
查阅文档,我们得知, Int() 函数是从 default Source (默认源)中产生的伪随机数。
而这个 default Source ,我们从Seed 部分可以看到,如果你没有设置随机种子,那么默认初始种子总是从 1 开始。
既然随机种子一样,那自然其结果也是一样的。
随机的伪随机数
我们已经知道了默认随机种子是从 1 开始,那么我们只要在每次生成随机数之前先设置一个不一样的种子,那么其结果自然也就不一样了。
我们要尽可能保证每次伪随机数生成器工作时使用的是不同的种子,通常的做法是采用当前时间作为种子。
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
rand.Seed(int64(time.Now().UnixNano()))
fmt.Println(rand.Int())
}
这样,由于种子不同,我们每次运行的结果也就不一样。我们就能达到获取伪随机数的目的啦。
真随机数
如果我们的应用对安全性要求比较高,需要使用真随机数的话,那么可以使用 crypto/rand 包中的方法。
package main
import (
"crypto/rand"
"fmt"
"math/big"
)
func main() {
// 生成 20 个 [0, 100) 范围的真随机数。
for i := 0; i < 20; i++ {
result, _ := rand.Int(rand.Reader, big.NewInt(100))
fmt.Println(result)
}
}
上面的程序每次运行的结果都是不一样的,会真正随机的生成随机数。
访问:https://github.com/sqrthree/sqrthree.github.io/issues
来源:https://juejin.im/post/5ab0c7f06fb9a028d936fe5c
猜你喜欢
- 用户管理是绝大部分Web网站都需要解决的问题。用户管理涉及到用户注册和登录。用户注册相对简单,我们可以先通过API把用户注册这个功能实现了:
- python是一个很有趣的语言,可以在命令行窗口运行。python中有很多功能强大的模块,这篇经验告诉你,如何使用python的pygal模
- 本文实例讲述了JS实现淘宝支付宝网站的控制台菜单效果。分享给大家供大家参考。具体如下:这是一款支付宝网站中的控制台总菜单,可实现动画效果的显
- 使用SQL SERVER的[导入]功能,便可将access数据转换,但要注意原来的'自增字段'需要修改,将相应字段标识修改为
- 楔子Python 有一个第三方模块叫 psutil,专门用来获取操作系统以及硬件相关的信息,比如:CPU、磁盘、网络、内存等等。下面来看一下
- 如何显示一个文本文件?完整显示文本文件的代码如下: Write(STRING) WriteLine(STRING) WriteBlan
- 本文实例讲述了Python使用当前时间、随机数产生一个唯一数字的方法。分享给大家供大家参考,具体如下:Python生成当前时间很简单,比Ja
- asp禁止站外盗链,站外提交方法、以及asp判断星期几方法.防盗链,主要通过判断上一页面来源是否是本站来实现的,不是本站的链接就
- 以下插件是我在项目中经常使用的jQuery插件,不见得是最好的,但是我目前接触到的jQuery插件中最适合我的。01. jQuery.Fle
- 目录简介环境要求:安装小试一下创建爬虫将请求头转为json格式使用简介feapder 是一款上手简单,功能强大的Python爬虫框架,使用方
- python提供了4种方式来满足进程间的数据通信1. 使用multiprocessing.Queue可以在进程间通信,但不能在Pool池创建
- 但是,具有identity特性的字段,不需要具有唯一性,更不必须是主键。 可以通过,set identity_insert tablenam
- 本文会把学习过程中遇到的一些小问题和解决办法放在这里,以便于大家能够更好地学习python。一、Python的异常处理因为想到自己不断尝试写
- 1.函数参数# 1.位置参数:调用函数时,传入的值需要按照位置顺序传入# 实例:求x的n次方def xPowN(x,n): &
- 1.创建图在tensorflow中,一个程序默认是建立一个图的,除了系统自动建立图以外,我们还可以手动建立图,并做一些其他的操作。下面我们使
- Python的线程操作在旧版本中使用的是thread模块,在Python27和Python3中引入了threading模块,同时thread
- HTML文档与CSS的关联常见有4种方式:1.使用link标记<link rel="stylesheet"
- 前言上一节我们讲解了数据类型以及字符串中几个需要注意的地方,这节我们继续讲讲字符串行数同时也讲其他内容和穿插的内容,简短的内容,深入的讲解。
- 对于经常使用MYSQL的人来说,phpmyadmin是一个必备的工具。这个工具非常强大,几乎可以完成所有的数据库操作,但是它也有一个弱点,对
- Protobuf是google开发的一个序列化和反序列化的协议库,我们可以自己设计传递数据的格式,通过.proto文件定义我们的要传递的数据