Golang: math/rand 和 crypto/rand 区别
1. 前言
原文地址
之前发现了golang标准库中又两个rand软件包,开始非常想知道他们之间的差异.
math/rand
软件包可以用于简单的游戏,但不能用于真正的随机性。
-
math/rand
: 伪随机数生成器 -
crypto/rand
: 加密安全的随机数生成器
Rob Pike的代码
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
c := fanIn(boring("Joe"), boring("Ann"))
for i := 0; i < 10; i++ {
fmt.Println(<-c)
}
fmt.Println("You're both boring; I'm leaving.")
}
func boring(msg string) <-chan string {
c := make(chan string)
go func() {
for i := 0; ; i++ {
c <- fmt.Sprintf("%s %d", msg, i)
time.Sleep(time.Duration(rand.Intn(1e3)) * time.Millisecond)
}
}()
return c
}
// FAN IN
func fanIn(input1, input2 <-chan string) <-chan string {
c := make(chan string)
go func() {
for {
c <- <-input1
}
}()
go func() {
for {
c <- <-input2
}
}()
return c
}
2. Math/rand 伪随机数生成器
实现伪随机数生成器。
随机数由源生成。顶级函数(例如Float64和Int)使用默认的共享源,该源在每次运行程序时都会产生确定的值序列。 如果每次运行需要不同的行为, 请使用种子函数初始化默认的源。 默认的Source可安全地供多个goroutine并发使用,但不是由NewSource创建的Source。
package main
import (
"fmt"
"math/rand"
"time"
)
func init(){
rand.Seed(time.Now().UTC().UnixNano())
}
func main() {
// launches 2 generators and the fanIn collector function
c := fanIn(genrt(), genrt())
for i := 0; i < 10000; i++ {
fmt.Println(<-c)
}
}
func fanIn(a <-chan int, b <-chan int) <-chan string {
c := make(chan string)
// launch collector from a to channel
go func() {
var count int
for {
count += <-a
c <- fmt.Sprintf("Tally of A is: %d", count)
}
}()
// launch collector from b to channel
go func() {
var count int
for {
count += <-b
c <- fmt.Sprintf("Tally of B is: %d", count)
}
}()
return c
}
func genrt() <-chan int {
c := make(chan int)
// launch generator of Dice rolls
go func() {
for i := 0; ; i++ {
c <- rand.Intn(6) + 1
time.Sleep(time.Duration(500 * time.Millisecond))
}
}()
return c
}
打印输出
...
Tally of B is: 17656
Tally of A is: 17438
Tally of A is: 17440
Tally of B is: 17659
Tally of B is: 17660
Tally of A is: 17445
3. Crypto/rand 加密安全的随机数生成器
实现了加密安全的随机数生成器。
package main
import (
"crypto/rand"
"fmt"
"math/big"
"time"
)
func main() {
// launches 2 generatores and the fanIn collector function
c := fanIn(genrt(), genrt())
for i := 0; i < 10000; i++ {
fmt.Println(<-c)
}
}
func fanIn(a <-chan int, b <-chan int) <-chan string {
c := make(chan string)
// launch collector from a to channel
go func() {
var count int
for {
count += <-a
c <- fmt.Sprintf("Tally of A is: %d", count)
}
}()
// launch collector from b to channel
go func() {
var count int
for {
count += <-b
c <- fmt.Sprintf("Tally of B is: %d", count)
}
}()
return c
}
func genrt() <-chan int {
c := make(chan int)
// launch generator of Dice rolls
go func() {
for i := 0; ; i++ {
dice, err := rand.Int(rand.Reader, big.NewInt(6))
if err != nil {
fmt.Println(err)
}
c <- int(dice.Int64()) + 1
time.Sleep(time.Duration(1 * time.Millisecond))
}
}()
return c
}
打印输出
...
Tally of B is: 17496
Tally of A is: 17570
Tally of A is: 17574
Tally of B is: 17500
Tally of B is: 17505
Tally of A is: 17576
golang后端
Go语言后端技术分享,希望 [链接]的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交...
推荐阅读
Go语言详解:HTTP断点续传多线程下载原理
原文地址:Go语言详解:HTTP断点续传多线程下载原理
mojotv_cn阅读 2k
前端如何入门 Go 语言
类比法是一种学习方法,它是通过将新知识与已知知识进行比较,从而加深对新知识的理解。在学习 Go 语言的过程中,我发现,通过类比已有的前端知识,可以更好地理解 Go 语言的特性。
robin赞 23阅读 3.2k评论 6
Golang 中 []byte 与 string 转换
string 类型和 []byte 类型是我们编程时最常使用到的数据结构。本文将探讨两者之间的转换方式,通过分析它们之间的内在联系来拨开迷雾。
机器铃砍菜刀赞 24阅读 57.9k评论 2
年度最佳【golang】map详解
这篇文章主要讲 map 的赋值、删除、查询、扩容的具体执行过程,仍然是从底层的角度展开。结合源码,看完本文一定会彻底明白 map 底层原理。
去去1002赞 16阅读 11.5k评论 2
年度最佳【golang】GMP调度详解
Golang最大的特色可以说是协程(goroutine)了, 协程让本来很复杂的异步编程变得简单, 让程序员不再需要面对回调地狱, 虽然现在引入了协程的语言越来越多, 但go中的协程仍然是实现的是最彻底的. 这篇文章将通过分析...
去去1002赞 15阅读 11.9k评论 4
万字详解,吃透 MongoDB!
MongoDB 是一个基于 分布式文件存储 的开源 NoSQL 数据库系统,由 C++ 编写的。MongoDB 提供了 面向文档 的存储方式,操作起来比较简单和容易,支持“无模式”的数据建模,可以存储比较复杂的数据类型,是一款非常...
JavaGuide赞 8阅读 1.6k
数据结构与算法:二分查找
一、常见数据结构简单数据结构(必须理解和掌握)有序数据结构:栈、队列、链表。有序数据结构省空间(储存空间小)无序数据结构:集合、字典、散列表,无序数据结构省时间(读取时间快)复杂数据结构树、 堆图二...
白鲸鱼赞 9阅读 5.2k
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。