英文:
When reading rand.Reader may result in error?
问题
我是否正确理解,crypto/rand.Reader 只会在未列出的平台上返回读取错误,即当它实际上未被实现时?
// Reader 是一个全局共享的强加密伪随机生成器实例。
//
// 在 Linux 上,如果可用,Reader 使用 getrandom(2),否则使用 /dev/urandom。
// 在 OpenBSD 上,Reader 使用 getentropy(2)。
// 在其他类 Unix 系统上,Reader 从 /dev/urandom 读取。
// 在 Windows 系统上,Reader 使用 CryptGenRandom API。
var Reader io.Reader
英文:
Do I understand correctly that crypto/rand.Reader can return Read error only on platforms not listed below, i.e. when it is not actually implemented?
// Reader is a global, shared instance of a cryptographically
// strong pseudo-random generator.
//
// On Linux, Reader uses getrandom(2) if available, /dev/urandom otherwise.
// On OpenBSD, Reader uses getentropy(2).
// On other Unix-like systems, Reader reads from /dev/urandom.
// On Windows systems, Reader uses the CryptGenRandom API.
var Reader io.Reader
答案1
得分: 10
TL;DR:crypto/rand
的Read()
(和Reader.Read()
)方法可能因各种原因而失败,即使在支持的平台上也是如此。不要假设调用这些函数会始终成功。始终检查error
返回值。
>我理解正确,crypto/rand.Reader
只会在未列出的平台上返回读取错误,即实际上未实现时才会返回错误吗?
不是。例如,看一下rand.Reader
的Linux实现。如果可用,该实现将使用getrandom
Linux系统调用,该调用可能会失败并返回多个错误(最重要的是EAGAIN
):
> EAGAIN
- 请求的熵不可用,并且如果未设置GRND_NONBLOCK
标志,getrandom()
将阻塞。
EAGAIN
错误字面上告诉你“稍后再试”;根据man 3 errno
的官方含义是“资源暂时不可用”。因此,当收到EAGAIN
错误时,你可以简单地在一定时间内继续尝试。
如果getrandom
不可用,crypto/rand
模块将尝试打开并从/dev/urandom
读取(参见源代码),这也可能因各种原因而失败。这些错误可能不一定是暂时性的(例如,与文件系统权限有关的问题);如果你的应用程序依赖于随机数据的可用性,你应该将错误视为应用程序中的任何其他不可恢复的错误。
因此,你不应该假设rand.Read()
在Linux/UNIX上总是成功,并且始终检查rand.Read()
的错误返回值。
英文:
TL;DR; crypto/rand
's Read()
(and Reader.Read()
) methods may fail due to a variety of reasons, even on the platforms listed as supported. Do not assume that calls to this functions will always succeed. Always check the error
return value.
<hr />
>Do I understand correctly that crypto/rand.Reader can return Read error only on platforms not listed below, i.e. when it is not actually implemented?
No. For example, have a look at the Linux implementation of rand.Reader
. If available, this implementation will use the getrandom
Linux system call, which may fail with a number of errors (most importantly, EAGAIN
):
> EAGAIN
- The requested entropy was not available, and getrandom()
would
have blocked if the GRND_NONBLOCK
flag was not set.
The EAGAIN
error quite literally tells you to "try again later"; the official meaning according to man 3 errno
is "Resource temporarily unavailable". So when receiving an EAGAIN
error you could simply keep trying for a certain time.
If getrandom
is not available, the crypto/rand
module will try to open and read from /dev/urandom
(see source code), which might also fail for any number of reasons. These errors might not necessarily be of temporary nature (for example, issues with file system permissions); if your application depends on the availability of random data, you should treat an error like any other kind of non-recoverable error in your application.
For these reasons, you should not assume that rand.Read()
will always succeed on Linux/UNIX and always check rand.Read()
's error return value.
答案2
得分: 0
Reader是封装基本Read方法的接口。
Read将最多len(p)个字节读入p中。它返回读取的字节数(0 <= n <= len(p))和遇到的任何错误。即使Read返回n < len(p),在调用期间它也可能使用p的所有内容作为临时空间。如果有一些数据可用但不足len(p)个字节,Read通常会返回可用的数据,而不是等待更多数据。
当Read在成功读取n > 0个字节后遇到错误或文件结束条件时,它返回读取的字节数。它可以从同一次调用中返回(非nil)错误,也可以从后续调用中返回错误(以及n == 0)。这种一般情况的一个实例是,在输入流的末尾返回非零字节数的Reader可能返回err == EOF或err == nil。下一次Read应该返回0,EOF。
在考虑错误err之前,调用者应始终处理返回的n > 0个字节。这样做可以正确处理在读取一些字节后发生的I/O错误,以及两种允许的EOF行为。
除非len(p) == 0,否则不建议Read的实现返回零字节计数和nil错误。调用者应将返回的0和nil视为表示什么都没有发生;特别是它不表示EOF。
实现不得保留p。
type Reader interface {
Read(p []byte) (n int, err error)
}
不,io.Reader
会返回错误。
英文:
> type io.Reader
>
> Reader is the interface that wraps the basic Read method.
>
> 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.
>
> When Read encounters an error or end-of-file condition after
> successfully reading n > 0 bytes, it returns the number of bytes read.
> It may return the (non-nil) error from the same call or return the
> error (and n == 0) from a subsequent call. An instance of this general
> case is that a Reader returning a non-zero number of bytes at the end
> of the input stream may return either err == EOF or err == nil. The
> next Read should return 0, EOF.
>
> Callers should always process the n > 0 bytes returned before
> considering the error err. Doing so correctly handles I/O errors that
> happen after reading some bytes and also both of the allowed EOF
> behaviors.
>
> Implementations of Read are discouraged from returning a zero byte
> count with a nil error, except when len(p) == 0. Callers should treat
> a return of 0 and nil as indicating that nothing happened; in
> particular it does not indicate EOF.
>
> Implementations must not retain p.
>
> type Reader interface {
> Read(p []byte) (n int, err error)
> }
No. io.Reader
s return errors.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论