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阅读 2.2k
又一款眼前一亮的Linux终端工具!
今天给大家介绍一款最近发现的功能十分强大,颜值非常高的一款终端工具。这个神器我是在其他公众号文章上看到的,但他们都没把它的强大之处介绍明白,所以我自己体验一波后,再向大家分享自己的体验。
良许赞 6阅读 1.9k
「刷起来」Go必看的进阶面试题详解
逃逸分析是Go语言中的一项重要优化技术,可以帮助程序减少内存分配和垃圾回收的开销,从而提高程序的性能。下面是一道涉及逃逸分析的面试题及其详解。
王中阳Go赞 4阅读 2k评论 1
初学后端,如何做好表结构设计?
这篇文章介绍了设计数据库表结构应该考虑的4个方面,还有优雅设计的6个原则,举了一个例子分享了我的设计思路,为了提高性能我们也要从多方面考虑缓存问题。
王中阳Go赞 4阅读 1.8k评论 2
一分钟搞明白!快速掌握 Go WebAssembly
最近因为各种奇怪的原因,更多的接触到了 WebAssembly。虽然之前很多博客也翻过写过各种文章,但总感觉欠些味道。于是今天梳理了一版,和大家一起展开学习。
煎鱼赞 4阅读 2.3k
go 协程操作map导致的数据竞争及解决方法
有个查询结果集的操作,无可避免的需要在循环获取数据,然后将结果集放到 map 中,这个操作在压测的时候,没出现问题,发布到生产环境之后,开始偶现 fatal error: concurrent map read and map write 错误,导致...
hxd_赞 5阅读 900评论 4
Linux终端居然也可以做文件浏览器?
大家好,我是良许。在抖音上做直播已经整整 5 个月了,我很自豪我一路坚持到了现在【笑脸】最近我在做直播的时候,也开始学习鱼皮大佬,直播写代码。当然我不懂 Java 后端,因此就写写自己擅长的 Shell 脚本。但...
良许赞 1阅读 2.1k
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。