在 Go 中生成隨機(jī)的安全密碼
你可以使用 Go 編程語(yǔ)言? 提供的隨機(jī)數(shù)生成器來(lái)生成由 ASCII 字符組成的難以猜測(cè)的密碼。盡管本文中提供的代碼很容易閱讀,但是你仍需要了解 Go 的基礎(chǔ)知識(shí),才能更好地理解它。如果你是對(duì) Go 還不熟悉,請(qǐng)閱讀 Go 語(yǔ)言之旅 來(lái)了解更多信息,然后返回此處。
在介紹實(shí)用程序和它的代碼之前,讓我們先來(lái)看看這個(gè) ASCII 表的子集,它可以在 ??man 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 字符中,可打印字符的十進(jìn)制值范圍為 33 到 126,其他的 ASCII 值都不適合用于密碼。因此,本文介紹的實(shí)用程序?qū)⑸稍摲秶鷥?nèi)的 ASCII 字符。
生成隨機(jī)整數(shù)
第一個(gè)實(shí)用程序名為 ??random.go?
?,它生成指定數(shù)量的隨機(jī)整數(shù),這些整數(shù)位于給定范圍內(nèi)。??random.go?
? 最重要的部分是這個(gè)函數(shù):
func random(min, max int) int {
return rand.Intn(max-min) + min
}
此函數(shù)使用了 ??rand.Intn()?
? 函數(shù)來(lái)生成一個(gè)屬于給定范圍的隨機(jī)整數(shù)。請(qǐng)注意,??rand.Intn()?
? 返回一個(gè)屬于 ??[0,n)?
? 的非負(fù)隨機(jī)整數(shù)。如果它的參數(shù)是一個(gè)負(fù)數(shù),這個(gè)函數(shù)將會(huì)拋出異常,異常消息是:??panic: invalid argument to Intn?
?。你可以在 ??math/rand 文檔?? 中找到 ??math/rand?
? 包的使用說(shuō)明。
??random.go?
? 實(shí)用程序接受三個(gè)命令行參數(shù):生成的整數(shù)的最小值、最大值和個(gè)數(shù)。
編譯和執(zhí)行 ??random.go?
? 會(huì)產(chǎn)生這樣的輸出:
$ 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 中生成更安全的隨機(jī)數(shù),請(qǐng)使用 Go 庫(kù)中的 ??crypto/rand?
? 包。
生成隨機(jī)密碼
第二個(gè)實(shí)用程序 ??randomPass.go?
? 用于生成隨機(jī)密碼。??randomPass.go?
? 使用 ??random()?
? 函數(shù)來(lái)生成隨機(jī)整數(shù),它們隨后被以下 Go 代碼轉(zhuǎn)換為 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 表中第一個(gè)可打印的字符(十進(jìn)制 ASCII 碼為 ??33?
?)。因此,所有生成的 ASCII 字符都位于 ??!?
? 和 ??~?
? 之間,后者的十進(jìn)制 ASCII 碼為 ??126?
?。
因此,生成的每個(gè)隨機(jī)數(shù)都大于 ??MIN?
?,小于 ??MAX?
?,并轉(zhuǎn)換為 ASCII 字符。該過(guò)程繼續(xù)進(jìn)行,直到生成的密碼達(dá)到指定的長(zhǎng)度。
??randomPass.go?
? 實(shí)用程序接受單個(gè)(可選)命令行參數(shù),以定義生成密碼的長(zhǎng)度,默認(rèn)值為 8,這是一個(gè)非常常見(jiàn)的密碼長(zhǎng)度。執(zhí)行 ??randomPass.go?
? 會(huì)得到類似下面的輸出:
$ go run randomPass.go 1
Z
$ go run randomPass.go 10
#Cw^a#IwkT
$ go run randomPass.go
Using default values!
[PP8@'Ci
最后一個(gè)細(xì)節(jié):不要忘記調(diào)用 ??rand.Seed()?
?,并提供一個(gè)種子seed值,以初始化隨機(jī)數(shù)生成器。如果你始終使用相同的種子值,隨機(jī)數(shù)生成器將生成相同的隨機(jī)整數(shù)序列。
隨機(jī)數(shù)生成代碼
你可以在 ??GitHub?? 找到 ??random.go?
? 和 ??randomPass.go?
? 的源碼。你也可以直接在 ??play.golang.org?? 上執(zhí)行它們。
我希望這篇文章對(duì)你有所幫助。