hamacs/ha-passwords.org
Howard Abrams 01a0958e6f Update the copyright year
This really was a lark to see if I could change ALL the files using
woccur and a regular expression. Quite please with how simple that was.
2023-02-23 09:35:36 -08:00

3.8 KiB

Personal Password Generator

A literate programming version for Emacs code to generate and store passwords.

Introduction

Let's assume that I store a bunch of words in data files:

  (defvar ha-passwords-data-files (list (expand-file-name "adjectives.txt"
                                                          (expand-file-name "data" hamacs-source-dir))
                                        (expand-file-name "colors.txt"
                                                          (expand-file-name "data" hamacs-source-dir))
                                        (expand-file-name "nouns.txt"
                                                          (expand-file-name "data" hamacs-source-dir)))
    "List of file name containing a data lines for our password generator. Order of these files matter.")

  (defvar ha-passwords-data nil
    "Contains a list of lists of words that we can choose.")

You can see where I'm going with this, can't you? Let's read them into list variables.

  (defun ha-passwords--read-data-file (filename)
    (with-temp-buffer
      (insert-file-contents filename)
      (split-string (buffer-string) "\n" t)))

Now we get three or so words from our list of lists:

  (defun ha-passwords-words ()
    (unless ha-passwords-data
      (setq ha-passwords-data
            (--map (ha-passwords--read-data-file it) ha-passwords-data-files)))

    (--map (nth (random (length it)) it) ha-passwords-data))

Let's make a password:

  (defun ha-passwords-generate (&optional separator)
    (unless separator
      (setq separator "-"))

    (let* ((choices '("!" "@" "#" "$" "%" "^" "&" "*"))
           (choice (random (length choices)))
           (number (1+ choice)))
      (->> (ha-passwords-words)
           (s-join separator)
           (s-capitalize)
           (s-append (nth choice choices))
           (s-append (number-to-string number)))))
  (defun generate-password (&optional separator)
    (interactive)
    (let ((passphrase (ha-passwords-generate separator)))
      (kill-new passphrase)
      (message "Random password: %s" passphrase)))

Keybindings

Got make it easy to call:

  (ha-leader "a g" '("generate passwd" . generate-password))