135 lines
4.3 KiB
Text
135 lines
4.3 KiB
Text
import "random" for Random
|
|
import "./ioutil" for FileUtil, File, Input
|
|
import "./fmt" for Fmt
|
|
import "os" for Process
|
|
|
|
var r = Random.new()
|
|
var rr = Random.new() // use a separate generator for shuffles
|
|
var lb = FileUtil.lineBreak
|
|
|
|
var lower = "abcdefghijklmnopqrstuvwxyz"
|
|
var upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
var digit = "0123456789"
|
|
var other = """!"#$%&'()*+,-./:;<=>?@[]^_{|}~"""
|
|
|
|
var exclChars = [
|
|
"'I', 'l' and '1'",
|
|
"'O' and '0' ",
|
|
"'5' and 'S' ",
|
|
"'2' and 'Z' "
|
|
]
|
|
|
|
var shuffle = Fn.new { |s|
|
|
var sl = s.toList
|
|
rr.shuffle(sl)
|
|
return sl.join()
|
|
}
|
|
|
|
var generatePasswords = Fn.new { |pwdLen, pwdNum, toConsole, toFile|
|
|
var ll = lower.count
|
|
var ul = upper.count
|
|
var dl = digit.count
|
|
var ol = other.count
|
|
var tl = ll + ul + dl + ol
|
|
var fw = toFile ? File.create("pwds.txt") : null
|
|
|
|
if (toConsole) System.print("\nThe generated passwords are:")
|
|
for (i in 0...pwdNum) {
|
|
var pwd = lower[r.int(ll)] + upper[r.int(ul)] + digit[r.int(dl)] + other[r.int(ol)]
|
|
for (j in 0...pwdLen - 4) {
|
|
var k = r.int(tl)
|
|
pwd = pwd + ((k < ll) ? lower[k] :
|
|
(k < ll + ul) ? upper[k - ll] :
|
|
(k < tl - ol) ? digit[k - ll - ul] : other[tl - 1 - k])
|
|
}
|
|
for (i in 1..5) pwd = shuffle.call(pwd) // shuffle 5 times say
|
|
if (toConsole) Fmt.print(" $2d: $s", i + 1, pwd)
|
|
if (toFile) {
|
|
fw.writeBytes(pwd)
|
|
if (i < pwdNum - 1) fw.writeBytes(lb)
|
|
}
|
|
}
|
|
if (toFile) {
|
|
System.print("\nThe generated passwords have been written to the file pwds.txt")
|
|
fw.close()
|
|
}
|
|
}
|
|
|
|
var printHelp = Fn.new {
|
|
System.print("""
|
|
This program generates up to 99 passwords of between 5 and 20 characters in
|
|
length.
|
|
|
|
You will be prompted for the values of all parameters when the program is run
|
|
- there are no command line options to memorize.
|
|
|
|
The passwords can either be written to the console or to a file (pwds.txt),
|
|
or both.
|
|
|
|
The passwords must contain at least one each of the following character types:
|
|
lower-case letters : a -> z
|
|
upper-case letters : A -> Z
|
|
digits : 0 -> 9
|
|
other characters : !"#$%&'()*+,-./:;<=>?@[]^_{|}~
|
|
|
|
Optionally, a seed can be set for the random generator
|
|
(any non-zero number) otherwise the default seed will be used.
|
|
Even if the same seed is set, the passwords won't necessarily be exactly
|
|
the same on each run as additional random shuffles are always performed.
|
|
|
|
You can also specify that various sets of visually similar characters
|
|
will be excluded (or not) from the passwords, namely: Il1 O0 5S 2Z
|
|
|
|
Finally, the only command line options permitted are -h and -help which
|
|
will display this page and then exit.
|
|
|
|
Any other command line parameters will simply be ignored and the program
|
|
will be run normally.
|
|
|
|
""")
|
|
}
|
|
|
|
var args = Process.arguments
|
|
if (args.count == 1 && (args[0] == "-h" || args[0] == "-help")) {
|
|
printHelp.call()
|
|
return
|
|
}
|
|
|
|
System.print("Please enter the following and press return after each one")
|
|
|
|
var pwdLen = Input.integer(" Password length (5 to 20) : ", 5, 20)
|
|
var pwdNum = Input.integer(" Number to generate (1 to 99) : ", 1, 99)
|
|
|
|
var seed = Input.number (" Seed value (0 to use default) : ")
|
|
if (seed != 0) r = Random.new(seed)
|
|
|
|
System.print(" Exclude the following visually similar characters")
|
|
for (i in 0..3) {
|
|
var yn = Input.option(" %(exclChars[i]) y/n : ", "ynYN")
|
|
if (yn == "y" || yn == "Y") {
|
|
if (i == 0) {
|
|
upper = upper.replace("I", "")
|
|
lower = lower.replace("l", "")
|
|
digit = digit.replace("1", "")
|
|
} else if (i == 1) {
|
|
upper = upper.replace("O", "")
|
|
digit = digit.replace("0", "")
|
|
} else if (i == 2) {
|
|
upper = upper.replace("S", "")
|
|
digit = digit.replace("5", "")
|
|
} else if (i == 3) {
|
|
upper = upper.replace("Z", "")
|
|
digit = digit.replace("2", "")
|
|
}
|
|
}
|
|
}
|
|
|
|
var toConsole = Input.option(" Write to console y/n : ", "ynYN")
|
|
toConsole = toConsole == "y" || toConsole == "Y"
|
|
var toFile = true
|
|
if (toConsole) {
|
|
toFile = Input.option(" Write to file y/n : ", "ynYN")
|
|
toFile = toFile == "y" || toFile == "Y"
|
|
}
|
|
|
|
generatePasswords.call(pwdLen, pwdNum, toConsole, toFile)
|