Personal Password Generator
Table of Contents
A literate programming version for Emacs code to generate and store passwords.
Overlay Redaction
Love this idea for using a regular expression to redact (or at least, obscure) sensitive information before screen sharing.
(defun toggle-redact-buffer (regexp) "Redact buffer content matching regexp. A space redacts all." (interactive (list (read-regexp "Text to Redact (Regexp)" 'regexp-history-last))) (let* ((redacted) (matches (let ((results '())) (when (string-empty-p regexp) (setq regexp "[[:graph:]]") (setq regexp-history-last regexp) (add-to-history 'regexp-history regexp)) (save-excursion (goto-char (point-min)) (while (re-search-forward regexp nil t) (push (cons (match-beginning 0) (match-end 0)) results))) (nreverse results)))) (mapc (lambda (match) (dolist (overlay (overlays-in (car match) (cdr match))) (setq redacted t) (delete-overlay overlay)) (unless redacted (overlay-put (make-overlay (car match) (cdr match)) 'display (make-string (- (cdr match) (car match)) ?x)))) matches)))
I’m not sure how often I will use this, so I’m not putting it on a keybinding, also so, I will also not put a name-spacing prefix on the function.
Password Generation
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))