分享
  1. 首页
  2. 文章

Golang: math/rand 和 crypto/rand 区别

TechMojotv · · 1171 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

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

有疑问加站长微信联系(非本文作者)

本文来自:Segmentfault

感谢作者:TechMojotv

查看原文:Golang: math/rand 和 crypto/rand 区别

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
1171 次点击
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏