;;; Code:
+;; Generate totp code
+
(require 'bindat)
(require 'gnutls)
(require 'hexl)
(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.
(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