Beale’s Cipher
December 2, 2016
The book cipher is unusual because different data structures are appropriate for enciphering and deciphering operations. We begin with enciphering:
(define (encipher key txt) (define (clean txt) (filter (lambda (c) (not (char-whitespace? c))) (map char-downcase (string->list txt)))) (let ((alpha (make-vector 26 (list)))) (do ((key (map (lambda (s) (string-ref s 0)) (string-split #\space key)) (cdr key)) (i 1 (+ i 1))) ((null? key)) (let ((x (- (char->integer (car key)) 97))) (vector-set! alpha x (cons i (vector-ref alpha x))))) (map (lambda (c) (let ((xs (vector-ref alpha (- (char->integer c) 97)))) (if (null? xs) 0 (fortune xs)))) (clean txt))))
Here, alpha
as a 26-slot vector, one slot per letter of the alphabet, with each slot containing a list of the indices of the words that begin with that letter. For instance, the key “now is the time” is stored as a vector #(() () () () () () () () (2) () () () () (1) () () () () () (3 4) () () () () () ()). Note that the index numbers of the key words start at 1, not 0. At each letter of plain text, one of the key word indices corresponding to that letter is chosen at random (by the fortune
function); plain text letters that do not appear in the key text are encoded as 0.
For deciphering, the initial letters of the words in the key text are stored in a vector, one letter per vector slot, and index numbers are looked up in the vector, applying an offset of 1; an underscore is written if a 0 appears in the cipher text:
(define (decipher key xs) (let ((alpha (list->vector (map (lambda (s) (string-ref s 0)) (string-split #\space key))))) (list->string (map (lambda (x) (if (zero? x) #\_ (vector-ref alpha (- x 1)))) xs))))
Here are some examples:
> (encipher "now is the time" "tin") (4 2 1) > (decipher "now is the time" '(4 2 1)) "tin"
Unfortunately, Beale misnumbered the words in the Declaration of Independence, and made several other clerical errors during his encipherment, so the resulting message is garbled:
> (decipher declaration text2) "ihaiedeposotedinthecopnttolbedoortaboupfourmilesfrombulordsinanepcaiationoriaul tsipfestbelowthesurlacsofthhgtoundthsfotlowingarticissbeaongingjoiotlttothepartf eswhoslnamfsategiietinnumberthrffhttewiththofirstdepositcottistcdoftenhptdredand loprteenpouetrofgoldatdtsirtteightsuodtedandtweiiepoundsofsilierdepositednoieigh teennineteenthesecondwatabdsdecfighteentwenttonlbntaonsisttdohninetffnhuedredand seienpoundsoogoldbtdtweliehundtedatdeightteightofsilieraisotewelsobtainedinsttou itinepchangetosbistransportationatdialuelaathirteetrhousanddollarstheaboieissecu tfltpackhdinitonpotswitswrotcoierstheiaultisrougsltlinedwttsstoneandtheiesselrre stonsolidstoneandarecoisrfdwiahothttspapernuaberonedescrialrthcopaatlocalittoots tiarlttothatnodifoiculttwillcesadttfindingit"
And here is the proper decipherment:
I have deposited in the county of Bedford, about four miles from Buford’s, in an excavation or vault, six feet below the surface of the ground, the following articles, belonging jointly to the parties whose names are given in number “3,” herewith:
The first deposit consisted of one thousand and fourteen pounds of gold, and three thousand eight hundred and twelve pounds of silver, deposited November, 1819. The second was made December, 1821, and consisted of nineteen hundred and seven pounds of gold, and twelve hundred and eighty-eight pounds of silver; also jewels, obtained in St. Louis in exchange for silver to save transportation, and valued at $13,000.
The above is securely packed in iron pots, with iron covers. The vault is roughly lined with stone, and the vessels rest on solid stone, and are covered with others. Paper number “1” describes the exact locality of the vault so that no difficulty will be had in finding it.
The Declaration of Independence and the cipher text of the second document appear on the next page. You can run the program at http://ideone.com/221v1J.
This was my 2nd ever programming course assignment, and the one I enjoyed programming the most. Thanks for posting this.
In Python. The Beale cipher is apparently so complicated to use, that Beale (probably) messed up the encoding. It is, of course, a daunting task to set up the encoding with a document of 1322 words without a computer. It is also not really known which version of the Declaration of Independence he used.
Sounds like a good excuse to play around with Unicode and ES6 a little more. ES6 has a number of features that make proper Unicode handling rather easier than in previous versions of Javascript. Notably, strings now support the new iterator protocol that allows us to easily convert strings to arrays of single Unicode characters rather than having to deal with surrogate pairs. For testing this, we will use texts in the Gothic script which uses the astral Unicode codepoints U+10330 to U+1034A, and seems to be reasonably well supported by fonts and browsers. Extant Gothic scripts are mainly religious, but there is one poem in Gothic, “Bagme Bloma”, written by J. R. R. Tolkein. Here we encrypt that poem, using as key text the Gothic version of the Lord’s Prayer. I couldn’t find the texts already in the Gothic script, so we start by converting from latin transliterations.
Here’s the output with the key text, the plain text and the decrypted cipher text, we can see one of the disadvantages of Beale’s scheme – some of the letters do not occur as first letter in the key text so cannot be enciphered:
In Ruby