2023-12-03 18:57:36 +00:00
#+title : Personal Password Generator
#+author : Howard X. Abrams
#+date : 2021-01-11
#+tags : emacs
2021-11-16 00:18:31 +00:00
A literate programming version for Emacs code to generate and store passwords.
2022-06-18 00:25:47 +00:00
#+begin_src emacs-lisp :exports none
2022-03-09 18:45:37 +00:00
;;; ha-passwords --- Emacs code to generate and store passwords. -*- lexical-binding: t; -* -
;;
2023-02-23 17:35:36 +00:00
;; © 2021-2023 Howard X. Abrams
2022-06-18 00:25:47 +00:00
;; Licensed under a Creative Commons Attribution 4.0 International License.
2022-03-09 18:45:37 +00:00
;; See http://creativecommons.org/licenses/by/4.0/
;;
;; Author: Howard X. Abrams <http://gitlab.com/howardabrams >
;; Maintainer: Howard X. Abrams
;; Created: January 11, 2021
;;
;; This file is not part of GNU Emacs.
;;
;; *NB:* Do not edit this file. Instead, edit the original literate file at:
2024-10-19 20:34:01 +00:00
;; ~/src/hamacs/ha-passwords.org
2022-03-09 18:45:37 +00:00
;; And tangle the file to recreate this one.
;;
;;; Code:
2022-06-18 00:25:47 +00:00
#+end_src
2023-09-18 17:32:59 +00:00
* Overlay Redaction
Love [[https://xenodium.com/redact-that-buffer/ ][this idea ]] for using a regular expression to /redact/ (or at least, obscure) sensitive information before screen sharing.
#+begin_src emacs-lisp
(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)))
#+end_src
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
2021-11-16 00:18:31 +00:00
Let's assume that I store a bunch of words in data files:
2022-06-18 00:25:47 +00:00
#+begin_src emacs-lisp
(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.")
#+end_src
2021-11-16 00:18:31 +00:00
You can see where I'm going with this, can't you? Let's read them into list variables.
2022-06-18 00:25:47 +00:00
#+begin_src emacs-lisp
(defun ha-passwords--read-data-file (filename)
(with-temp-buffer
(insert-file-contents filename)
(split-string (buffer-string) "\n" t)))
2021-11-16 00:18:31 +00:00
2022-06-18 00:25:47 +00:00
#+end_src
2021-11-16 00:18:31 +00:00
2022-06-18 00:25:47 +00:00
Now we get three or so words from our list of lists:
#+begin_src emacs-lisp
(defun ha-passwords-words ()
(unless ha-passwords-data
(setq ha-passwords-data
(--map (ha-passwords--read-data-file it) ha-passwords-data-files)))
2021-11-16 00:18:31 +00:00
2022-06-18 00:25:47 +00:00
(--map (nth (random (length it)) it) ha-passwords-data))
#+end_src
2021-11-16 00:18:31 +00:00
Let's make a password:
2022-06-18 00:25:47 +00:00
#+begin_src emacs-lisp
(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)))))
#+end_src
#+begin_src emacs-lisp
(defun generate-password (&optional separator)
(interactive)
(let ((passphrase (ha-passwords-generate separator)))
(kill-new passphrase)
(message "Random password: %s" passphrase)))
#+end_src
2021-11-16 00:18:31 +00:00
* Keybindings
Got make it easy to call:
2022-06-18 00:25:47 +00:00
#+begin_src emacs-lisp
(ha-leader "a g" '("generate passwd" . generate-password))
#+end_src
2021-11-16 00:18:31 +00:00
* Technical Artifacts :noexport:
This will =provide= a code name, so that we can =require= this.
2022-06-18 00:25:47 +00:00
#+begin_src emacs-lisp :exports none
(provide 'ha-passwords)
;;; ha-passwords.el ends here
#+end_src
2021-11-16 00:18:31 +00:00
2024-03-07 04:02:25 +00:00
#+description : A literate programming version for Emacs code to generate and store passwords.
2021-11-16 00:18:31 +00:00
2024-03-07 04:02:25 +00:00
#+property : header-args:sh :tangle no
#+property : header-args:emacs-lisp :tangle yes
#+property : header-args :results none :eval no-export :comments no mkdirp yes
2021-11-16 00:18:31 +00:00
2024-03-07 04:02:25 +00:00
#+options : num:nil toc:t todo:nil tasks:nil tags:nil date:nil
#+options : skip:nil author:nil email:nil creator:nil timestamp:nil
#+infojs_opt : view:nil toc:t ltoc:t mouse:underline buttons:0 path:http://orgmode.org/org-info.js