阅读rand.Reader可能会导致错误?

时间:2017-02-18 16:58:34

标签: go

我是否正确理解crypto / rand.Reader可以在下面未列出的平台上返回读取错误 ,即何时没有实际实现?

// 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

2 个答案:

答案 0 :(得分:6)

<强> TL; DR ; crypto/rand Read()(和Reader.Read())方法可能由于各种原因而失败,即使在列为受支持的平台上也是如此。 不要假设对此功能的调用始终成功。 始终检查error返回值。

  

我是否正确理解crypto / rand.Reader只能在下面未列出的平台上返回Read错误,即实际上没有实现?

即可。例如,请查看rand.Reader的{​​{3}}。如果可用,此实现将使用Linux implementation,这可能会因许多错误而失败(最重要的是,EAGAIN):

  

EAGAIN - 请求的熵不可用,getrandom()会                 如果未设置GRND_NONBLOCK标志,则已阻止。

EAGAIN错误确实告诉您&#34;稍后再试一次&#34 ;;根据{{​​3}}的官方含义是&#34;资源暂时不可用&#34; 。因此,当收到EAGAIN错误时,您可以继续尝试一段时间。

如果getrandom不可用,crypto/rand模块将尝试打开并从/dev/urandom读取(请参阅getrandom Linux system call),这可能因各种原因而失败。这些错误可能不一定是临时性的(例如,文件系统权限问题);如果您的应用程序取决于随机数据的可用性,您应该像处理应用程序中的任何其他类型的不可恢复错误一样处理错误。

出于这些原因,您应该假设rand.Read()将始终在Linux / UNIX上成功并且始终检查rand.Read()&#39; s错误返回值。

答案 1 :(得分:0)

  

type io.Reader

     

Reader是包装基本Read方法的接口。

     

读取读取最多len(p)个字节到p。它返回字节数   读取(0&lt; = n&lt; = len(p))并遇到任何错误。即使阅读   返回n&lt; len(p),它可以使用所有p作为临时空间   呼叫。如果某些数据可用但不是len(p)字节,则读取   通常会返回可用的内容,而不是等待更多内容。

     

Read之后遇到错误或文件结束条件   成功阅读n&gt; 0字节,它返回读取的字节数。   它可能会从同一个调用返回(非零)错误或返回   来自后续调用的错误(和n == 0)。这个将军的一个例子   case是一个Reader在结尾返回非零字节数   输入流可以返回err == EOF或err == nil。该   next Read应返回0,EOF。

     

来电者应始终处理n&gt;之前返回0个字节   考虑到错误错误。这样做可以正确处理I / O错误   在读取一些字节以及两个允许的EOF之后发生   的行为。

     

不鼓励读取的实现返回零字节   使用nil错误计数,除非len(p)== 0.来电者应该对待   返回0和nil表示没有发生任何事情;在   特别是它没有表明EOF。

     

实施不得保留p。

type Reader interface {
        Read(p []byte) (n int, err error)
}

没有。 io.Reader返回错误。