zoukankan      html  css  js  c++  java
  • go标准库的学习-crypto/rand

    参考:https://studygolang.com/pkgdoc

    导入方式:

    import "crypto/rand"

    rand包实现了用于加解密的更安全的随机数生成器。

    Variables 

    var Reader io.Reader

    Reader是一个全局、共享的密码用强随机数生成器。在Unix类型系统中,会从/dev/urandom读取;而Windows中会调用CryptGenRandom API。

    举例说明该如何使用Reader:

    package main 
    import(
        "fmt"
        "encoding/base64"
        "crypto/rand"
        "io"
    )
    
    //sessionId函数用来生成一个session ID,即session的唯一标识符
    func sessionId() string {
        b := make([]byte, 32)
        //ReadFull从rand.Reader精确地读取len(b)字节数据填充进b
        //rand.Reader是一个全局、共享的密码用强随机数生成器
        if _, err := io.ReadFull(rand.Reader, b); err != nil { 
            return ""
        }
        fmt.Println(b) //[62 186 123 16 209 19 130 218 146 136 171 211 12 233 45 99 80 200 59 20 56 254 170 110 59 147 223 177 48 136 220 142]
        return base64.URLEncoding.EncodeToString(b)//将生成的随机数b编码后返回字符串,该值则作为session ID
    }
    func main() { 
        fmt.Println(sessionId()) //Prp7ENETgtqSiKvTDOktY1DIOxQ4_qpuO5PfsTCI3I4=
    }

    func Int

    func Int(rand io.Reader, max *big.Int) (n *big.Int, err error)

    返回一个在[0, max)区间服从均匀分布的随机值,如果max<=0则会panic。

    举例:

    package main 
    import(
        "fmt"
        "crypto/rand"
        "math/big"
    )
    
    
    func main() { 
        //从128开始,这样就能够将(max.BitLen() % 8) == 0的情况包含在里面
        for n := 128; n < 140; n++ {
            b := new(big.Int).SetInt64(int64(n)) //将new(big.Int)设为int64(n)并返回new(big.Int)
            fmt.Printf("max Int is : %v
    ", b)
            i, err := rand.Int(rand.Reader, b)
            if err != nil {
                fmt.Printf("Can't generate random value: %v, %v", i, err)
            }
            fmt.Printf("rand Int is : %v
    ", i)
        }
    }

    返回:

    bogon:~ user$ go run testGo.go 
    max Int is : 128
    rand Int is : 25
    max Int is : 129
    rand Int is : 117
    max Int is : 130
    rand Int is : 85
    max Int is : 131
    rand Int is : 62
    max Int is : 132
    rand Int is : 27
    max Int is : 133
    rand Int is : 120
    max Int is : 134
    rand Int is : 10
    max Int is : 135
    rand Int is : 27
    max Int is : 136
    rand Int is : 11
    max Int is : 137
    rand Int is : 119
    max Int is : 138
    rand Int is : 35
    max Int is : 139
    rand Int is : 83

    func Prime

    func Prime(rand io.Reader, bits int) (p *big.Int, err error)

    返回一个具有指定字位数的数字,该数字具有很高可能性是质数。如果从rand读取时出错,或者bits<2会返回错误。

    举例:

    package main 
    import(
        "fmt"
        "crypto/rand"
    )
    
    
    func main() { 
        for n := 2; n < 10; n++ {
            p, err := rand.Prime(rand.Reader, n) //n代表位数,比如3为2位,127为7位
            if err != nil {
                fmt.Printf("Can't generate %d-bit prime: %v", n, err)
            }
            if p.BitLen() != n { //返回p的绝对值的字位数,0的字位数为0
                fmt.Printf("%v is not %d-bit", p, n)
            }
            if !p.ProbablyPrime(32) { //对p进行32次Miller-Rabin质数检测。如果方法返回真则p是质数的几率为1-(1/4)**32;否则p不是质数
                fmt.Printf("%v is not prime", p)
            }
            fmt.Println(p)
        }
    }

    返回:

    bogon:~ user$ go run testGo.go 
    3
    7
    13
    31
    53
    109
    223
    439

    如果位数小于2的话,会报错:

    package main 
    import(
        "fmt"
        "crypto/rand"
        "log"
    )
    
    
    func main() { 
        p, err := rand.Prime(rand.Reader, 1) //n代表位数,比如3为2位,127为7位
        if err != nil {
            log.Fatal(err)
        }
        fmt.Println(p)
    }

    返回:

    bogon:~ user$ go run testGo.go 
    2019/02/23 12:31:37 crypto/rand: prime size must be at least 2-bit
    exit status 1

    func Read

    func Read(b []byte) (n int, err error)

    本函数是一个使用io.ReadFull调用Reader.Read的辅助性函数。当且仅当err == nil时,返回值n == len(b)。

    因为本函数是一个使用io.ReadFull调用Reader.Read的辅助性函数,所以最上面的那个生成session ID的例子等价于:

    package main 
    import(
        "fmt"
        "encoding/base64"
        "crypto/rand"
    )
    
    //sessionId函数用来生成一个session ID,即session的唯一标识符
    func sessionId() string {
        b := make([]byte, 32)
        //rand.Reader是一个全局、共享的密码用强随机数生成器
        n, err := rand.Read(b);
        if err != nil { 
            return ""
        }
        fmt.Println(b[:n]) //[154 94 244 2 147 96 148 6 13 27 3 52 231 127 160 159 40 47 84 116 79 87 160 217 185 216 47 143 101 107 219 178]
        return base64.URLEncoding.EncodeToString(b)//将生成的随机数b编码后返回字符串,该值则作为session ID
    }
    func main() { 
        fmt.Println(sessionId()) //ml70ApNglAYNGwM053-gnygvVHRPV6DZudgvj2Vr27I=
    }
  • 相关阅读:
    IE8的parseInt
    powershell小工具
    判断请求是不是ajax
    常用命令行/批处理
    服务器导出服务器时间转换浏览器端时区
    用批处理批量编译多个解决方案(.sln)
    shell脚本批量调用git命令
    批处理(.bat)For命令使用
    360doc的文章不能复制的解决办法
    XSD笔记
  • 原文地址:https://www.cnblogs.com/wanghui-garcia/p/10421659.html
Copyright © 2011-2022 走看看