2022-08-01 Making secrets with Emacs

Let’s play with encryption!

Well, not real encryption – but fun encryption. And few things are more fun than playing ciphers with kids!

Emacs already has excellent support for ROT13 (and more general Caesar ciphers) using rot13-region and message-caesar-region commands (which see). It also has rot13-other-window, which displays the current buffer, rot13-encoded, in another window, updated live. There is also morse-region, which can morse-encode text. (It also has the reverse, unmorse-region; while not really useful for cipher games, there is also nato-region and denato-region.)

However, I wanted another cipher. Well, not really a cipher per se, since it is a non-injective function (i.e., two different plaintexts may result in the same “ciphertext”) – but it is fun anyway. The idea is to take a sentence, sort the letters in every word alphabetically, and sort the resulting “words” alphabetically, too. (The idea is inspired by Emanuel Berg’s post on help-gnu-emacs.) This way, I could prepare secret messages for my kids to decipher. Fun! (I also bought a few geocaches to hide the messages in various places, effectively creating a linked list – each one has a hint about where to find the next one – for them to find.)

Here is a simple function to encode a sentence like this.

(defun encode-with-alphabetic-cipher (string)
  "Encode STRING alphabetically.
This means sorting letters in every word
alphabetically and then sort all these \"words\"
alphabetically, too."
  (mapconcat #'identity
	     (seq-sort #'string<
		       (mapcar
			(lambda (word)
			  (seq-sort #'< word))
			(split-string string)))
	     " "))

For example, (encode-with-alphabetic-cipher "The quick brown fox jumps over the lazy dog") evaluates to "Teh alyz bnorw cikqu dgo eht eorv fox jmpsu". As you can see, it’s far from perfect (for example, it sorts uppercase letters before lowercase ones – obviously, as they come earlier in ASCII – so that I need to remember to give it all caps or all lowercase), but the result is pretty nice. (If I wanted anything more fancy, I could easily fix that, make this into a command acting on a region, etc.)

Of course, much more can be done. Apart from Morse code (and NATO code, which is much less interesting for this type of play) I could easily implement Braille alphabet (which – apart from being another way to encrypt messages for my kids for fun – could enable me to discuss important and difficult topics like blindness with them!). Incidentally, the Morse (and NATO) codes are implemented in lisp/play/morse.el file in Emacs Git repo, and the first revision comes from rms himself and is dated 1995. Apparently, I was not the only one using it;-), since it received a bug fix in 2021! Just a random tidbit from Emacs history.

Anyway, that’s it for today.

CategoryEnglish, CategoryBlog, CategoryEmacs