在 Go 中创建随机、安全的密码

Go 的随机数生成器是生成难以猜测的密码的好方法。
332 位读者喜欢这篇文章。
Password laptop

geralt,通过 Pixabay。CC0。

您可以使用 Go 编程语言 提供的随机数生成器来生成由 ASCII 字符组成的难以猜测的密码。尽管本文中提供的代码易于阅读,但如果您已经了解 Go 的基础知识,则最好理解它。如果您是该编程语言的新手,请参加 Go 语言之旅 以了解更多信息,然后再回到这里。

在我们深入研究实用程序和代码之前,请查看 man ascii 命令输出中找到的 ASCII 表的子集

 30 40 50 60 70 80 90 100 110 120
 ---------------------------------
0:    (  2  <  F  P  Z  d   n   x
1:    )  3  =  G  Q  [  e   o   y
2:    *  4  >  H  R  \  f   p   z
3: !  +  5  ?  I  S  ]  g   q   {
4: "  ,  6  @  J  T  ^  h   r   |
5: #  -  7  A  K  U  _  i   s   }
6: $  .  8  B  L  V  `  j   t   ~
7: %  /  9  C  M  W  a  k   u  DEL
8: &  0  :  D  N  X  b  l   v
9: '  1  ;  E  O  Y  c  m   w

可打印 ASCII 字符的十进制值范围为 33 到 126;没有其他 ASCII 值适合包含在密码中。因此,本文中提供的实用程序将生成该范围内的 ASCII 字符。

创建随机整数

第一个实用程序名为 random.go,它生成指定数量的、位于给定范围内的随机整数。random.go 最重要的部分是这个函数

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

此函数使用 Go 函数 rand.Intn() 生成属于给定范围的随机整数。请注意,rand.Intn() 返回一个属于 [0,n) 的非负随机数;如果其参数为负数,则该函数将 panic。panic 消息将是 panic: invalid argument to Intn。您可以在 math/rand 文档 中找到 math/rand 包的文档。

random.go 实用程序接受三个命令行参数:生成的整数的最小值、最大值以及将生成的整数的数量。

编译和执行 random.go 将创建如下输出

$ go build random.go
$ ./random
Usage: ./random MIX MAX TOTAL
$ ./random 1 3 10
2 2 1 2 2 1 1 2 2 1

如果您希望在 Go 中生成更安全的随机数,请使用 Go 库的 crypto/rand 包。

创建随机密码

第二个实用程序 randomPass.go 生成随机密码。randomPass.go 使用 random() 函数生成随机数,这些随机数将使用以下 Go 代码转换为 ASCII 字符

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

MIN 的值为 0,MAX 的值为 94,而 startChar 的值为 !,它是 ASCII 表中的第一个可打印字符(十进制 ASCII 代码为 33)。因此,所有将生成的 ASCII 字符都位于 ! 之后和 ~ 字符之前,后者的十进制 ASCII 代码为 126

因此,生成的每个随机数都大于 MIN,小于 MAX,并转换为 ASCII 字符。该过程一直持续到生成的密码达到所需的长度。

randomPass.go 实用程序接受一个(可选)命令行参数,该参数定义生成的密码的长度。其默认值为 8,这是一个非常常见的密码长度。执行 randomPass.go 将生成以下类型的输出

$ go run randomPass.go 1
Z
$ go run randomPass.go 10
#Cw^a#IwkT
$ go run randomPass.go
Using default values!
[PP8@'Ci

最后一个细节:不要忘记使用种子值调用 rand.Seed() 以初始化随机数生成器。如果您始终使用相同的种子值,则随机数生成器将创建相同的随机整数序列。

Random number generator code

您可以在 GitHub 上找到 random.gorandomPass.go。您也可以在 play.golang.org 上执行它。

我希望这篇文章对您有所帮助。如果您有任何问题,请在下方留言或在 Twitter 上与我联系。

User profile image.
Mihalis Tsoukalos 是一位技术作家、UNIX 管理员和开发人员、DBA 和数学家。他是《Go 系统编程》和《精通 Go》的作者。您可以通过 http://www.mtsoukalos.eu/ 和 https://twitter.com/mactsouk 联系他。

6 条评论

很棒的文章。
我不理解 startChar[0] 部分,它是否指向字符 "!"?

假设我想扩展程序以至少包含一个特殊字符,我需要将 MIN 和 MAX 设置为 0 和 14 吗?

如果我想仅限于数字,我需要将 MIN 和 MAX 设置为 15 和 24 吗?
谢谢

你好!

是的,startChar[0] 指向字符 "!",它是 ASCII 表中的第一个可打印字符。

您想包含哪种特殊字符?ASCII 表包含不可打印字符,这些字符很可能无法在密码中使用。

如果只想限制为数字,则 MIN 仍然为 0,但 MAX 应为 11。但是,您需要将 startChar 变量的值更改为 "0"。

我喜欢你关于随机数的文章。我也在努力改进安全的密码策略。目前,安全级别非常好,因为只有非常有才华的程序员才能破解随机数密码策略。大多数用户甚至不知道如何在计算机上输入内容。这应该牢记在心。70% 的人甚至需要帮助才能在计算机上打字。对于这些人来说,非常弱的密码策略也很难应对。这实际上是事实。计算机科学专业的学生等情况除外。但是,计算机病毒可能具有破坏性,而不是人。

感谢您的评论 - 我很高兴您喜欢我的文章。

实用程序的名称是 cryptoRand.go :)

Creative Commons License本作品采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可。
© . All rights reserved.