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.