生成随机字符串

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

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

  1. package main
  2. import (
  3. "fmt"
  4. "math/rand"
  5. "os"
  6. "strconv"
  7. "time"
  8. )
  9. func random(min, max int) int {
  10. return rand.Intn(max-min) + min
  11. }

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

  1. func main() {
  2. MIN := 0
  3. MAX := 94
  4. SEED := time.Now().Unix()
  5. var LENGTH int64 = 8
  6. arguments := os.Arg

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

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

  1. switch len(arguments) {
  2. case 2:
  3. LENGTH, _ = strconv.ParseInt(os.Args[1], 10, 64)
  4. default:
  5. fmt.Println("Using default values!")
  6. }
  7. rand.Seed(SEED)

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

  1. startChar := "!"
  2. var i int64 = 1
  3. for {
  4. myRand := random(MIN, MAX)
  5. newChar := string(startChar[0] + byte(myRand))
  6. fmt.Print(newChar)
  7. if i == LENGTH {
  8. break
  9. }
  10. i++
  11. }
  12. fmt.Println()
  13. }

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

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

在你最喜欢的 Unix shell 中输入 man ascii 就能生成易读的 ASCII 字符表。

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

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