溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

go語言如何生成隨機(jī)數(shù)和隨機(jī)字符串

發(fā)布時(shí)間:2021-12-08 17:06:41 來源:億速云 閱讀:145 作者:小新 欄目:開發(fā)技術(shù)

小編給大家分享一下go語言如何生成隨機(jī)數(shù)和隨機(jī)字符串,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

生成隨機(jī)數(shù)

隨機(jī)數(shù)的生成是計(jì)算機(jī)科學(xué)的一個(gè)研究領(lǐng)域,同時(shí)也是一種藝術(shù)。這是因?yàn)橛?jì)算機(jī)是純粹的邏輯機(jī)器,所以使用計(jì)算機(jī)生成隨機(jī)數(shù)異常困難!

你可以用 math/rand 包來生成隨機(jī)數(shù)。開始生成隨機(jī)數(shù)之前首先需要一個(gè)種子,種子用于整個(gè)過程的初始化,它相當(dāng)重要。因?yàn)槿绻忝看味加猛瑯拥姆N子初始化,那么就總是會得到相同的隨機(jī)數(shù)序列。這意味著每個(gè)人都可以重新生成同一個(gè)序列,那這個(gè)序列就根本不能再算是隨機(jī)的了!

我們將用來生成隨機(jī)數(shù)的程序名為 randomNumbers.go,下面分成四個(gè)部分進(jìn)行介紹。這個(gè)程序需要幾個(gè)參數(shù),分別是生成隨機(jī)數(shù)的下限、生成隨機(jī)數(shù)的上限、生成隨機(jī)數(shù)的數(shù)量。如果你還用了第四個(gè)命令參數(shù),那么程序會將它作為隨機(jī)數(shù)生成器的種子。在測試的時(shí)候,你就可以再次使用這個(gè)參數(shù)生成相同的數(shù)列。

程序的第一部分如下所示:

package main

import (
    "fmt"
    "math/rand"
    "os"
    "strconv"
    "time"
)

func random(min, max int) int {
    return rand.Intn(max-min) + min
}

random() 函數(shù)完成了所有的工作,它通過根據(jù)指定的范圍調(diào)用 rand.Intn() 生成隨機(jī)數(shù)。

這個(gè)命令行程序的第二部分如下:

func main() {
    MIN := 0
    MAX := 100
    TOTAL := 100
    SEED := time.Now().Unix()

    arguments := os.Args

這一部分對程序中將會用到的變量進(jìn)行了初始化。

randomNumbers.go 的第三部分包含如下的 Go 代碼:

switch len(arguments) {
    case 2:
        fmt.Println("Usage: ./randomNumbers MIN MAX TOTAL SEED")
        MIN, _ = strconv.Atoi(arguments[1])
        MAX = MIN + 100
    case 3:
        fmt.Println("Usage: ./randomNumbers MIN MAX TOTAL SEED")
        MIN, _ = strconv.Atoi(arguments[1])
        MAX, _ = strconv.Atoi(arguments[2])
    case 4:
        fmt.Println("Usage: ./randomNumbers MIN MAX TOTAL SEED")
        MIN, _ = strconv.Atoi(arguments[1])
        MAX, _ = strconv.Atoi(arguments[2])
        TOTAL, _ = strconv.Atoi(arguments[3])
    case 5:
        MIN, _ = strconv.Atoi(arguments[1])
        MAX, _ = strconv.Atoi(arguments[2])
        TOTAL, _ = strconv.Atoi(arguments[3])
        SEED, _ = strconv.ParseInt(arguments[4], 10, 64)
    default:
        fmt.Println("Using default values!")
    }

switch 代碼塊背后的邏輯相對簡單:根據(jù)命令行參數(shù)的數(shù)量決定程序中的參數(shù)是使用缺省的默認(rèn)值還是使用用戶提供的值。為了簡化程序,strconv.Atoi() 和 strconv.ParseInt() 函數(shù)返回的 error 參數(shù)使用下劃線字符接收,然后被忽略。如果是商業(yè)程序就千萬不能忽略 strconv.Atoi() 和 strconv.ParseInt() 函數(shù)返回的 error 參數(shù)!

最后,使用 strconv.ParseInt() 對 SEED 變量賦新的值是因?yàn)?rand.Seed() 函數(shù)要求的參數(shù)類型是 int64。strconv.ParseInt() 的第一個(gè)參數(shù)是要解析的字符串,第二個(gè)參數(shù)是輸出數(shù)的基數(shù),第三個(gè)參數(shù)是輸出數(shù)的位數(shù)。由于我們想要生成的是一個(gè) 64 位的十進(jìn)制整數(shù),所以使用 10 作為基數(shù),使用 64 作為位數(shù)。注意,如果你想解析無符號的整數(shù)的話應(yīng)該使用 strconv.ParseUint() 函數(shù)代替。

randomNumbers.go 的最后一部分是如下的 Go 代碼:

rand.Seed(SEED)
    for i := 0; i < TOTAL; i++ {
        myrand := random(MIN, MAX)
        fmt.Print(myrand)
        fmt.Print(" ")
    }
    fmt.Println()
}

除了使用 Unix 時(shí)間戳作為隨機(jī)數(shù)生成器的種子,你還可以使用 /dev/random 這個(gè)系統(tǒng)設(shè)備。你可以在第 8 章“Go Unix系統(tǒng)編程”中了解 /dev/random 的相關(guān)內(nèi)容。

執(zhí)行 randomNumbers.go 將會生成如下輸出:

$ go run randomNumbers.go
75 69 15 75 62 67 64 8 73 1 83 92 7 34 8 70 22 58 38 8 54 91 65 1 50 76 5 82 61 90 10 38 40 63 6 28 51 54 49 27 52 92 76 35 44 9 66 76 90 10 29 22 20 83 33 92 80 50 62 26 19 45 56 75 40 30 97 23 87 10 43 11 42 65 80 82 25 53 27 51 99 88 53 36 37 73 52 61 4 81 71 57 30 72 51 55 62 63 79
$ go run randomNumbers.go 1 3 2
Usage: ./randomNumbers MIN MAX TOTAL SEED
1 1 
$ go run randomNumbers.go 1 3 2
Usage: ./randomNumbers MIN MAX TOTAL SEED
2 2
$ go run randomNumbers.go 1 5 10 10
3 1 4 4 1 1 4 4 4 3
$ go run randomNumbers.go 1 5 10 10
3 1 4 4 1 1 4 4 4 3

如果你對隨機(jī)數(shù)生成真的很有興趣,那么你應(yīng)該先讀一下 Donald E.Knuth 寫的 The Art of Computer Programming (Addison-Wesley Professional, 2011) 的第二卷。

如果需要用 Go 生成更安全的隨機(jī)數(shù)的話,你可以使用 crypto/rand 包。這個(gè)包中實(shí)現(xiàn)了滿足密碼學(xué)安全的偽隨機(jī)數(shù)生成器。你可以在 https://golang.org/pkg/crypto/rand/ 文檔頁面了解更多關(guān)于 crypto/rand 包的信息。

生成隨機(jī)字符串

一旦你知道了計(jì)算機(jī)是如何呈現(xiàn)出單個(gè)字符,從隨機(jī)數(shù)過渡到隨機(jī)字符串就不難了。這一節(jié)將會介紹如何使用前一節(jié)中 randomNumbers.go 的代碼生成難以猜出的密碼。用于完成這個(gè)任務(wù)的 Go 程序叫做 generatePassword.go,下面將分四個(gè)部分進(jìn)行介紹。這個(gè)程序只需要一個(gè)命令行參數(shù),就是你需要生成的密碼的長度。

generatePassword.go 的第一部分包含如下的 Go 代碼:

package main

import (
    "fmt"
    "math/rand"
    "os"
    "strconv"
    "time"
)

func random(min, max int) int {
    return rand.Intn(max-min) + min
}

generatePassword.go 的第二個(gè)代碼段如下:

func main() {
    MIN := 0
    MAX := 94
    SEED := time.Now().Unix()
    var LENGTH int64 = 8

    arguments := os.Arg

我們只想得到可打印的 ASCII 字符,所以對生成隨機(jī)數(shù)的范圍進(jìn)行了限制。ASCII 字符表中可打印的字符一共有 94 個(gè)。這意味著該程序生成的隨機(jī)數(shù)的范圍應(yīng)該是從 0 到 94 且不包括 94。

generatePassword.go 的第三個(gè)代碼段如下:

switch len(arguments) {
    case 2:
        LENGTH, _ = strconv.ParseInt(os.Args[1], 10, 64)
    default:
        fmt.Println("Using default values!")
    }

       rand.Seed(SEED)

generatePassword.go 的最后一部分如下:

startChar := "!"
    var i int64 = 1
    for {
        myRand := random(MIN, MAX)
        newChar := string(startChar[0] + byte(myRand))
        fmt.Print(newChar)
        if i == LENGTH {
            break
        }
        i++
    }
    fmt.Println()
}

startChar 參數(shù)保存了這個(gè)程序可以生成的第一個(gè) ASCII 字符,也就是十進(jìn)制 ASCII 值為 33 的感嘆號。已知該程序生成的隨機(jī)數(shù)小于 94,可以計(jì)算出生成的最大的 ASCII 值為 93 + 33,等于 126,也就是 ~ 的 ASCII 值。下面的輸出是含有十進(jìn)制數(shù)值的 ASCII 字符表:

The decimal set:

  0 nul    1 soh    2 stx    3 etx    4 eot    5 enq    6 ack    7 bel
  8 bs     9 ht    10 nl    11 vt    12 np    13 cr    14 so    15 si
 16 dle   17 dc1   18 dc2   19 dc3   20 dc4   21 nak   22 syn   23 etb
 24 can   25 em    26 sub   27 esc   28 fs    29 gs    30 rs    31 us
 32 sp    33  !    34  "    35  #    36  $    37  %    38  &    39  '
 40  (    41  )    42  *    43  +    44  ,    45  -    46  .    47  /
 48  0    49  1    50  2    51  3    52  4    53  5    54  6    55  7
 56  8    57  9    58  :    59  ;    60  <    61  =    62  >    63  ?
 64  @    65  A    66  B    67  C    68  D    69  E    70  F    71  G
 72  H    73  I    74  J    75  K    76  L    77  M    78  N    79  O
 80  P    81  Q    82  R    83  S    84  T    85  U    86  V    87  W
 88  X    89  Y    90  Z    91  [    92  \    93  ]    94  ^    95  _
 96  `    97  a    98  b    99  c   100  d   101  e   102  f   103  g
104  h   105  i   106  j   107  k   108  l   109  m   110  n   111  o
112  p   113  q   114  r   115  s   116  t   117  u   118  v   119  w
120  x   121  y   122  z   123  {   124  |   125  }   126  ~   127 del

在你最喜歡的 Unix shell 中輸入 man ascii 就能生成易讀的 ASCII 字符表。

執(zhí)行 generatePassword.go 并傳入合適的命令行參數(shù)將生成如下輸出:

$ go run generatePassword.go
Using default values!
ugs$5mv1
$ go run generatePassword.go
Using default values!
PA/8hA@?
$ go run generatePassword.go 20
HBR+=3\UA'B@ExT4QG|o
$ go run generatePassword.go 20
XLcr|R{*pX/::'t2u^T'

以上是“go語言如何生成隨機(jī)數(shù)和隨機(jī)字符串”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識,歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI