192 lines
5.6 KiB
Kotlin
192 lines
5.6 KiB
Kotlin
// version 1.1.4-3
|
|
|
|
import java.util.Random
|
|
import java.io.File
|
|
|
|
val r = Random()
|
|
val rr = Random() // use a separate generator for shuffles
|
|
val ls = System.getProperty("line.separator")
|
|
|
|
var lower = "abcdefghijklmnopqrstuvwxyz"
|
|
var upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
var digit = "0123456789"
|
|
var other = """!"#$%&'()*+,-./:;<=>?@[]^_{|}~"""
|
|
|
|
val exclChars = arrayOf(
|
|
"'I', 'l' and '1'",
|
|
"'O' and '0' ",
|
|
"'5' and 'S' ",
|
|
"'2' and 'Z' "
|
|
)
|
|
|
|
fun String.shuffle(): String {
|
|
val sb = StringBuilder(this)
|
|
var n = sb.length
|
|
while (n > 1) {
|
|
val k = rr.nextInt(n--)
|
|
val t = sb[n]
|
|
sb[n] = sb[k]
|
|
sb[k] = t
|
|
}
|
|
return sb.toString()
|
|
}
|
|
|
|
fun generatePasswords(pwdLen: Int, pwdNum: Int, toConsole: Boolean, toFile: Boolean) {
|
|
val sb = StringBuilder()
|
|
val ll = lower.length
|
|
val ul = upper.length
|
|
val dl = digit.length
|
|
val ol = other.length
|
|
val tl = ll + ul + dl + ol
|
|
var fw = if (toFile) File("pwds.txt").writer() else null
|
|
|
|
if (toConsole) println("\nThe generated passwords are:")
|
|
for (i in 0 until pwdNum) {
|
|
sb.setLength(0)
|
|
sb.append(lower[r.nextInt(ll)])
|
|
sb.append(upper[r.nextInt(ul)])
|
|
sb.append(digit[r.nextInt(dl)])
|
|
sb.append(other[r.nextInt(ol)])
|
|
|
|
for (j in 0 until pwdLen - 4) {
|
|
val k = r.nextInt(tl)
|
|
sb.append(when (k) {
|
|
in 0 until ll -> lower[k]
|
|
in ll until ll + ul -> upper[k - ll]
|
|
in ll + ul until tl - ol -> digit[k - ll - ul]
|
|
else -> other[tl - 1 - k]
|
|
})
|
|
}
|
|
var pwd = sb.toString()
|
|
repeat(5) { pwd = pwd.shuffle() } // shuffle 5 times say
|
|
if (toConsole) println(" ${"%2d".format(i + 1)}: $pwd")
|
|
if (toFile) {
|
|
fw!!.write(pwd)
|
|
if (i < pwdNum - 1) fw.write(ls)
|
|
}
|
|
}
|
|
if (toFile) {
|
|
println("\nThe generated passwords have been written to the file pwds.txt")
|
|
fw!!.close()
|
|
}
|
|
}
|
|
|
|
fun printHelp() {
|
|
println("""
|
|
|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 Long integer) 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.
|
|
|
|
|
""".trimMargin())
|
|
}
|
|
|
|
fun main(args: Array<String>) {
|
|
if (args.size == 1 && (args[0] == "-h" || args[0] == "-help")) {
|
|
printHelp()
|
|
return
|
|
}
|
|
|
|
println("Please enter the following and press return after each one")
|
|
|
|
var pwdLen: Int?
|
|
do {
|
|
print(" Password length (5 to 20) : ")
|
|
pwdLen = readLine()!!.toIntOrNull() ?: 0
|
|
}
|
|
while (pwdLen !in 5..20)
|
|
|
|
var pwdNum: Int?
|
|
do {
|
|
print(" Number to generate (1 to 99) : ")
|
|
pwdNum = readLine()!!.toIntOrNull() ?: 0
|
|
}
|
|
while (pwdNum !in 1..99)
|
|
|
|
var seed: Long?
|
|
do {
|
|
print(" Seed value (0 to use default) : ")
|
|
seed = readLine()!!.toLongOrNull()
|
|
}
|
|
while (seed == null)
|
|
if (seed != 0L) r.setSeed(seed)
|
|
|
|
println(" Exclude the following visually similar characters")
|
|
for (i in 0..3) {
|
|
var yn: String
|
|
do {
|
|
print(" ${exclChars[i]} y/n : ")
|
|
yn = readLine()!!.toLowerCase()
|
|
}
|
|
while (yn != "y" && yn != "n")
|
|
if (yn == "y") {
|
|
when (i) {
|
|
0 -> {
|
|
upper = upper.replace("I", "")
|
|
lower = lower.replace("l", "")
|
|
digit = digit.replace("1", "")
|
|
}
|
|
|
|
1 -> {
|
|
upper = upper.replace("O", "")
|
|
digit = digit.replace("0", "")
|
|
}
|
|
|
|
2 -> {
|
|
upper = upper.replace("S", "")
|
|
digit = digit.replace("5", "")
|
|
}
|
|
|
|
3 -> {
|
|
upper = upper.replace("Z", "")
|
|
digit = digit.replace("2", "")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
var toConsole: Boolean?
|
|
do {
|
|
print(" Write to console y/n : ")
|
|
val t = readLine()!!
|
|
toConsole = if (t == "y") true else if (t == "n") false else null
|
|
}
|
|
while (toConsole == null)
|
|
|
|
var toFile: Boolean? = true
|
|
if (toConsole) {
|
|
do {
|
|
print(" Write to file y/n : ")
|
|
val t = readLine()!!
|
|
toFile = if (t == "y") true else if (t == "n") false else null
|
|
}
|
|
while (toFile == null)
|
|
}
|
|
|
|
generatePasswords(pwdLen!!, pwdNum!!, toConsole, toFile!!)
|
|
}
|