你可以使用下面的例子来生成一个长度可变的强随机密码串。显然,如果密码很短,它就不会很强!长密码也不一定意味着它很强。请阅读代码中的注释,以便你知道它到底是如何工作的。
package main
import (
"fmt"
"math/rand"
"strings"
"time"
)
var list = []string{
"(){}[]<>/+=-_,.~€#!@£$%^&*?|",
"0123456789",
"abcdefghijklmnopqrstuvwxyz",
"ABCDEFGHIJKLMNOPQRSTUVWXYZ",
}
// GeneratePlainPassword generates a random plain password string.
// It consists of four groups which are certain symbols, numbers,
// lower and upper case letters. As per the length and the remainder,
// character selecting is evenly distributed within these groups.
// Although it is unlikely, a final password might contain duplicated
// characters. If a specific character was selected previously, it gets
// dropped in order to increase randomness. Depending on the length
// this is repeated set amount of times to prevent infinite loop and
// applies to all four groups. Greater the length, greater chance in
// duplicated characters.
func GeneratePlainPassword(length int) (string, error) {
if length < 1 {
return "", nil
}
var (
retry int
group int
chars string
)
if length <= 4 {
retry = 1
} else if length > 20 && length <= 50 {
retry = 20
} else if length > 50 {
retry = 30
} else {
retry = 10
}
rand.Seed(time.Now().UnixNano())
for i := 1; i <= length; i++ {
switch group {
case 0:
pick(0, 31, retry, &chars)
group++
case 1:
pick(1, 10, retry, &chars)
group++
case 2:
pick(2, 26, retry, &chars)
group++
case 3:
pick(3, 26, retry, &chars)
group = 0
default:
return "", fmt.Errorf("out of group range")
}
}
psw := []byte(chars)
rand.Shuffle(length, func(i, j int) { psw[i], psw[j] = psw[j], psw[i] })
return string(psw), nil
}
func pick(key, len, retry int, chars *string) {
var try int
for {
try++
idx := rand.Intn(len)
char := list[key][idx:idx+1]
if !strings.Contains(*chars, char) || try == retry {
*chars += char
break
}
}
}
例子
RETRY: n/a
LENGTH: 0
PASSWR:
------------------------------------------------------------
RETRY: 1
LENGTH: 3
PASSWR: )4a
------------------------------------------------------------
RETRY: 10
LENGTH: 10
PASSWR: +i79d>W=4F
------------------------------------------------------------
RETRY: 20
LENGTH: 25
PASSWR: Mtm*d/>BN39?1y+J,kC54[8Lv
------------------------------------------------------------
RETRY: 30
LENGTH: 55
PASSWR: [QZ2b/=61.z]98^*Txqfst3!u£cS0#?XGVL%U3,0H1yj7KOmvr6&4C5
------------------------------------------------------------
RETRY: 30
LENGTH: 110
PASSWR: MaWYO)Bb3_&95O{qVn3kF,3]yT(R4~9P€7Z[l0N!0U&2#rw37J^Efgo£7.q)c8HL6?Sp44vm1/I=5@46h5stC}2i2uGe-X$zs|+A3xDj*Q4dK%