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\n", 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\n", 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=
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM