diff src/main/kotlin/name/blackcap/passman/Generate.kt @ 0:a6cfdffcaa94

Initial commit, incomplete but it runs sorta.
author David Barts <n5jrn@me.com>
date Sun, 11 Sep 2022 16:11:37 -0700
parents
children 698c4a3d758d
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/kotlin/name/blackcap/passman/Generate.kt	Sun Sep 11 16:11:37 2022 -0700
@@ -0,0 +1,61 @@
+package name.blackcap.passman
+
+import java.lang.IllegalArgumentException
+import java.security.SecureRandom
+import java.util.Random
+
+/* ASCII, alphanumeric, no 0's, 1's, I's, O's or l's to avoid confusion. */
+private const val DIGITS = "23456789"
+private const val UPPERS = "ABCDEFGHJKLMNPQRSTUVWXYZ"
+private const val LOWERS = "abcdefghijkmnopqrstuvwxyz"
+/* \ can confuse *NIX, |, ', and ` invite confusion */
+private const val SYMBOLS = "!\"#$%&()*+,-./:;<=>?@[]^_{}~"
+const val MIN_GENERATED_LENGTH = 6
+const val DEFAULT_GENERATED_LENGTH = 12
+
+fun generate(length: Int, allowSymbols: Boolean): CharArray {
+    /* insecure, and if REALLY short, causes bugs */
+    if (length < MIN_GENERATED_LENGTH) {
+        throw IllegalArgumentException("length of $length is less than $MIN_GENERATED_LENGTH")
+    }
+
+    /* determine allowed characters */
+    val passchars = if (allowSymbols) {
+        DIGITS + UPPERS + LOWERS + SYMBOLS
+    } else {
+        DIGITS + UPPERS + LOWERS
+    }
+
+    /* ensure we get one of each class of characters */
+    val randomizer = SecureRandom()
+    val generated = CharArray(length)
+    generated[0] = randomized(DIGITS, randomizer)
+    generated[1] = randomized(UPPERS, randomizer)
+    generated[2] = randomized(LOWERS, randomizer)
+    var i = 3
+    if (allowSymbols) {
+        generated[3] = randomized(SYMBOLS, randomizer)
+        i = 4
+    }
+
+    /* generate the rest of the characters */
+    while (i < length) {
+        generated[i++] = randomized(passchars, randomizer)
+    }
+
+    /* scramble them */
+    for (i in 0 until length) {
+        val j = randomizer.nextInt(length)
+        if (i != j) {
+            val temp = generated[i]
+            generated[i] = generated[j]
+            generated[j] = temp
+        }
+    }
+
+    /* AMF... */
+    return generated
+}
+
+private fun randomized(passchars: String, randomizer: Random): Char =
+    passchars[randomizer.nextInt(passchars.length)]