随笔 - 934, 文章 - 0, 评论 - 249, 阅读 - 345万

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

rand.Read() 和 io.ReadFull(rand.Reader) 的区别?

Posted on   蝈蝈俊  阅读(10218)  评论(0编辑  收藏  举报

golang的随机包 rand.go 中我们可以看到 rand.Read 其实是调用的io.Reader.Read()

   1: // Package rand implements a cryptographically secure
   2: // pseudorandom number generator.
   3: package rand
   4:  
   5: import "io"
   6:  
   7: // Reader is a global, shared instance of a cryptographically
   8: // strong pseudo-random generator.
   9: // On Unix-like systems, Reader reads from /dev/urandom.
  10: // On Windows systems, Reader uses the CryptGenRandom API.
  11: var Reader io.Reader
  12:  
  13: // Read is a helper function that calls Reader.Read.
  14: func Read(b []byte) (n int, err error) { return Reader.Read(b) }

io.Reader.Read() 函数的说明如下:

Read reads up to len(p) bytes into p. It returns the number of bytes read (0 <= n <= len(p)) and any error encountered. Even if Read returns n < len(p), it may use all of p as scratch space during the call. If some data is available but not len(p) bytes, Read conventionally returns what is available instead of waiting for more.

简单来说,它读出的数据,并不一定是指定长度的。

 

io.ReadFull 函数则相反:

ReadFull reads exactly len(buf) bytes from r into buf. It returns the number of bytes copied and an error if fewer bytes were read. The error is EOF only if no bytes were read. If an EOF happens after reading some but not all the bytes, ReadFull returns ErrUnexpectedEOF. On return, n == len(buf) if and only if err == nil.

读取正好len(buf)长度的字节。如果字节数不是指定长度,则返回错误信息和正确的字节数。

当没有字节能被读时,返回EOF错误。

如果读了一些,但是没读完产生EOF错误时,返回ErrUnexpectedEOF错误。

综上对比,获取随机数时,最好是下面的写法。

   1: import crand "crypto/rand"
   2:  
   3: r := make([]byte, length)
   4:  
   5: if _, err := io.ReadFull(crand.Reader, r); err != nil {
   6:     panic("error reading from random source: " + err.Error())
   7: }

 

参考资料:

rand.Read() or io.ReadFull(rand.Reader)?
https://groups.google.com/forum/#!topic/golang-nuts/eFS5GN-en3w

编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 记一次.NET内存居高不下排查解决与启示
点击右上角即可分享
微信分享提示