]> git.earman.xyz Git - emacsinit.git/commitdiff
Organize, add password generation
authorrearman <rearman@r717.net>
Thu, 18 Sep 2025 15:47:51 +0000 (11:47 -0400)
committerrearman <rearman@r717.net>
Thu, 18 Sep 2025 15:47:51 +0000 (11:47 -0400)
Defun to generate password of arbitrary length, with option to omit special
characters, and another to interactively insert the password into a file.  No
defun to copy to clipboard, since I'm assuming this will be mostly used while
creating a pass(1) compliant gpg file.

re/re-pass-alike.el

index b9550fb8c368810d7df522b7dbf91dc7a691b70f..734baeef25beb21c5f54b71e45782082836d5948 100644 (file)
@@ -3,6 +3,8 @@
 
 ;;; Code:
 
+;; Generate totp code
+
 (require 'bindat)
 (require 'gnutls)
 (require 'hexl)
@@ -75,16 +77,6 @@ required for HMAC-TOTP."
                (symbol-name filename))
              ".gpg"))))
 
-(defun get-password (&optional filename)
-  "Return a password given a file where it is stored.
-Assumes same structure as `pass(1)'."
-  (re/get-line-from-file (keyfile-string filename) 1))
-
-(defun password-to-clipboard (&optional filename)
-  "Copy the returned password to the clipboard."
-  (interactive)
-  (kill-new (get-password filename)))
-
 (defun get-totp (&optional filename)
   "Generate a totp code given a file with the secret hex string.
 If no filename given, prompt for one.
@@ -98,5 +90,72 @@ Also assumes the file is in `~/.password-store' and has the `.gpg' extension."
   (interactive)
   (kill-new (get-totp filename)))
 
+\f
+;; Find password from pass(1) entry
+
+(defun get-password (&optional filename)
+  "Return a password given a file where it is stored.
+Assumes same structure as `pass(1)'."
+  (re/get-line-from-file (keyfile-string filename) 1))
+
+(defun password-to-clipboard (&optional filename)
+  "Copy the returned password to the clipboard."
+  (interactive)
+  (kill-new (get-password filename)))
+
+\f
+;; Password generation
+
+(defconst *lowercase*
+  '("a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m"
+    "n" "o" "p" "q" "r" "s" "t" "u" "v" "w" "x" "y" "z")
+  "List of strings containing the lowercase English alphabet.")
+
+(defconst *uppercase*
+  '("A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M"
+    "N" "O" "P" "Q" "R" "S" "T" "U" "V" "W" "X" "Y" "Z")
+  "List of strings containing the uppercase English alphabet.")
+
+(defconst *numbers*
+  '("0" "1" "2" "3" "4" "5" "6" "7" "8" "9")
+  "List of strings containing the single-digit numbers.")
+
+(defconst *special-characters* '("!" "?" "$" "%" "&" "'" "(" ")" "*"
+                                "+" "," "-" "." "/" ":" ";" "<" "=" ">"
+                                "?" "@" "[" "]" "^" "_" "{" "|" "}" "~")
+  "List of strings containing the special visible characters excluding \\ and \" .")
+
+(defun pw-get-char (&optional no-special-chars)
+  "Select a single character at random to be used in a password.
+If `no-special-chars' is t, use only alpha-numeric characters."
+  (let ((selected-charset (append *lowercase*
+                                 *uppercase*
+                                 *numbers*
+                                 (when (null no-special-chars)
+                                   *special-characters*))))
+    (elt selected-charset (random (length selected-charset)))))
+
+(defun pw-get-chars (password-length &optional no-special-chars)
+  "Generate a list of characters as strings to be made into a password.
+If `no-special-chars' is t, use only alpha-numeric characters."
+  (append (list (pw-get-char no-special-chars))
+         (when (> password-length 1)
+           (pw-get-chars (- password-length 1) no-special-chars))))
+
+(defun generate-password (password-length &optional no-special-chars)
+  "Combine a list of randomly-selected characters into a single string of length given.
+calls `pw-get-chars'.  If `no-special-chars' is `t', use only alpha-numeric characters."
+  (apply #'concat (pw-get-chars password-length no-special-chars)))
+
+(defun insert-generated-password (&optional password-length)
+  "Insert a generated password into the current buffer.
+Negative password-length (or negative arg) sets `no-special-chars' for `generate-password'."
+  (interactive "p")
+  (let ((len (if (or (null password-length) (= 1 (abs password-length)))
+                16
+              (abs password-length)))
+       (no-special-p (and (numberp password-length) (< password-length 0))))
+    (insert (generate-password len no-special-p))))
+
 (provide 're-pass-alike)
 ;;; re-pass-alike.el ends here