05.10.1 生成随机字符串

一旦你知道了计算机是如何呈现出单个字符,从随机数过渡到随机字符串就不难了。这一节将会介绍如何使用前一节中 randomNumbers.go 的代码生成难以猜出的密码。用于完成这个任务的 Go 程序叫做 generatePassword.go,下面将分四个部分进行介绍。这个程序只需要一个命令行参数,就是你需要生成的密码的长度。

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 的第二个代码段如下:

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

    arguments := os.Arg

我们只想得到可打印的 ASCII 字符,所以对生成随机数的范围进行了限制。ASCII 字符表中可打印的字符一共有 94 个。这意味着该程序生成的随机数的范围应该是从 0 到 94 且不包括 94。

generatePassword.go 的第三个代码段如下:

    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 参数保存了这个程序可以生成的第一个 ASCII 字符,也就是十进制 ASCII 值为 33 的感叹号。已知该程序生成的随机数小于 94,可以计算出生成的最大的 ASCII 值为 93 + 33,等于 126,也就是 ~ 的 ASCII 值。下面的输出是含有十进制数值的 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 字符表。

执行 generatePassword.go 并传入合适的命令行参数将生成如下输出:

$ 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'

Last updated