The Laws of Cryptography:
The Beale Cipher

by Neal R. Wagner

Copyright © 2001 by Neal R. Wagner. All rights reserved.

NOTE: This site is obsolete. See book draft (in PDF):

Here is a Java implementation of the Beale cipher. As with the Caesar cipher, the program reads the input message from the standard input and outputs the ciphertext on the standard output. However, this program also reads a file to use as the key: key1.text in the first run and key1.text in the second run. The first key file is very simple -- just the letter d repeated over and over. This shows that the Beale cipher includes the Caesar cipher as a special case. The second key file is just another quotation (from B.F. Skinner). The program Beale.java only uses successive lowercase letters from a key file (and discards the other letters).


// Beale.java: implement the Beale cipher // Usage: java Beale (-d | -e) keyFile // The program reads a separate file (keyFile) for the key or pad. // The message is just the standard input. // Caps and punctuation marks in the message remain unchanged. // Only lowercase letters are used in the key file/ import java.io.*; public class Beale { private Reader messIn; // System.in for message private Reader keyIn; // keyFile for key file // Beale: constructor -- just open files public Beale(String keyFile) { messIn = new InputStreamReader(System.in); try { keyIn = new FileReader(keyFile); } catch (IOException e) { System.out.println("Exception opening keyFile"); } } // (en|de)crypt: just feed in opposite parameters public void encrypt() { translate(1); } public void decrypt() { translate(-1); } // translate: read keyFile and input, translate private void translate(int direction) { char c, key_c; while ((byte)(c = getNextChar(messIn)) != -1) { if (Character.isLowerCase(c)) { // fetch lowercase letter from key file while (!Character.isLowerCase(key_c = getNextChar(keyIn))) ; c = rotate(c, ((direction*(key_c - 'a')) + 26)%26); } System.out.print(c); } } // getNextChar: fetches next char. Also opens input file public char getNextChar(Reader in) { char ch = ' '; // = ' ' to keep compiler happy try { ch = (char)in.read(); } catch (IOException e) { System.out.println("Exception reading character"); } return ch; } // rotate: translate using rotation -- simpler version // This just uses arithmetic on char types, public char rotate(char c, int key) { int res = ((c - 'a') + key + 26)%26 + 'a'; return (char)res; } // main: check command, (en|de)crypt, feed in keyFile public static void main(String[] args) { if (args.length != 2) { System.out.println("Usage: java Beale (-d | -e) keyFile"); System.exit(1); } Beale cipher = new Beale(args[1]); if (args[0].equals("-e")) cipher.encrypt(); else if (args[0].equals("-d")) cipher.decrypt(); else { System.out.println("Usage: java Beale (-d | -e) keyFile"); System.exit(1); } } }
Here are the results of a run of the program where the key file consists of all letters "d", so that is does the same rotation by 3 as the previous example of the Caesar cipher:
% cat message.text
i returned, and saw under the sun, that the race is not to the swift,
nor the battle to the strong, neither yet bread to the wise, nor yet riches
to men of understanding, nor yet favour to men of skill; but time and chance
happeneth to them all.

% cat key1.text
dddddddddddddddddddddddddddddddddddddddddddddd
dddddddddddddddddddddddddddddddddddddddddddddd
dddddddddddddddddddddddddddddddddddddddddddddd
dddddddddddddddddddddddddddddddddddddddddddddd
dddddddddddddddddddddddddddddddddddddddddddddd
dddddddddddddddddddddddddddddddddddddddddddddd

% java Beale -e key1.text < message.text
l uhwxuqhg, dqg vdz xqghu wkh vxq, wkdw wkh udfh lv qrw wr wkh vzliw,
qru wkh edwwoh wr wkh vwurqj, qhlwkhu bhw euhdg wr wkh zlvh, qru bhw ulfkhv
wr phq ri xqghuvwdqglqj, qru bhw idyrxu wr phq ri vnloo; exw wlph dqg fkdqfh
kdsshqhwk wr wkhp doo.

% java Beale -e key1.text < message.text | java Beale -d key.text
i returned, and saw under the sun, that the race is not to the swift,
nor the battle to the strong, neither yet bread to the wise, nor yet riches
to men of understanding, nor yet favour to men of skill; but time and chance
happeneth to them all.

Notice that the ciphertext and decrpted plaintext has all the original punctuation characters, making it easier to break the system. Here is a run of a variation of the program that discards all characters except for lower-case letters:
% java Beale2 -e key1.text < message.text
luhwxuqhgdqgvdzxqghuwkhvxqwkdwwkhudfhlvqrwwrwkhvzliwqruwkhedwwohwrwkhvwurqjqhlwkhubhweuhdgwrwkhzlvhqrubhwulfkhvwrphqrixqghuvwdqglqjqrubhwidyrxuwrphqrivnlooexwwlphdqgfkdqfhkdsshqhwkwrwkhpdoo 

% java Beale2 -e key1.text < message.text | java Beale2 -d key1.text
ireturnedandsawunderthesunthattheraceisnottotheswiftnorthebattletothestrongneitheryetbreadtothewisenoryetrichestomenofunderstandingnoryetfavourtomenofskillbuttimeandchancehappenethtothemall

Finally, here is a real run with an actual non-trivial key file: key2.text. Recall that without knowing the text of the key file, this would be very difficult to cryptanalyze (break). For example, as before, the message ends with double letters: ll. However, this time the ciphertext ends with two different letters: gp.
% cat key2.text
A Golden Age, whether of art or music or science or peace or 
plenty, is out of reach of our economic and governmental techniques.  
something may be done by accident, as it has from time to time in the 
past, but not by deliberate intent.  At this very moment enormous 
numbers of intelligent men and women of good will are trying to build a 
better world.  But problems are born faster than they can be solved.  

% java Beale -e key2.text < message.text
w chxhxrak, egk wrk znuxf kty kcp, hysv blr teqv xw nqx hf isi fpgnl,
bik hmv favazj hi klg ggfavi, nrlzvzv prf fexao ms vor eymi, fgf kim yqpnqs
rp qhb bj vldgtaweawifo, gvr qjk tmowgv mc fmz sn fdppa; bmm ucfr oge akeykf
lrpiivrml gh malu sgp.

% java Beale -e key2.text < message.text | java Beale -d key2.text
i returned, and saw under the sun, that the race is not to the swift,
nor the battle to the strong, neither yet bread to the wise, nor yet riches
to men of understanding, nor yet favour to men of skill; but time and chance
happeneth to them all.

Here as before is a run that discards the punctuation characters:
% java Beale2 -e key2.text < message.text
wchxhxrakegkwrkznuxfktykcphysvblrteqvxwnqxhfisifpgnlbikhmvfavazjhiklgggfavinrlzvzvprffexaomsvoreymifgfkimyqpnqsrpqhbbjvldgtaweawifogvrqjktmowgvmcfmzsnfdppabmmucfrogeakeykflrpiivrmlghmalusgp

% java Beale2 -e key2.text < message.text | java Beale2 -d key2.text
ireturnedandsawunderthesunthattheraceisnottotheswiftnorthebattletothestrongneitheryetbreadtothewisenoryetrichestomenofunderstandingnoryetfavourtomenofskillbuttimeandchancehappenethtothemall


Revision date: 2001-07-29. (Please use ISO 8601, the International Standard.)