The Laws of Cryptography:
The Caesar 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 Caesar cipher. The program reads the input message from the standard input and outputs the ciphertext on the standard output. The key is an integer in the range from 0 to 25 inclusive, and one must use the same key for encryption and decryption. The program uses a function rotate to translate lowercase characters in a circle by a distance of key.


// Caesar.java: implement the Caesar cipher // This carries out a simple rotation of lower-case letters, // and does nothing to all other characters, making the decryption // process even easier, because caps and punctuation marks survive unchanged. // Usage: java Caesar (-d | -e) key // Above, option "-d" is for decryption, while "-e" is for encryption import java.io.*; public class Caesar { private Reader in; // standard input stream for message private int key; // (en|de)cryption key // Caesar: constructor, opens standard input, passes key public Caesar(int k) { // open file in = new InputStreamReader(System.in); key = k; } // (en|de)crypt: just feed in opposite parameters public void encrypt() { translate(key); } public void decrypt() { translate(-key); } // translate: input message, translate private void translate(int k) { char c; while ((byte)(c = getNextChar()) != -1) { if (Character.isLowerCase(c)) { c = rotate(c, k); } System.out.print(c); } } // getNextChar: fetches next char. public char getNextChar() { 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, version with table lookup public char rotate(char c, int key) { // c must be lowercase String s = "abcdefghijklmnopqrstuvwxyz"; int i = 0; while (i < 26) { // extra +26 below because key might be negative if (c == s.charAt(i)) return s.charAt((i + key + 26)%26); i++; } return c; } // main: check command, (en|de)crypt, feed in key value public static void main(String[] args) { if (args.length != 2) { System.out.println("Usage: java Caesar (-d | -e) key"); System.exit(1); } Caesar cipher = new Caesar(Integer.parseInt(args[1])); if (args[0].equals("-e")) cipher.encrypt(); else if (args[0].equals("-d")) cipher.decrypt(); else { System.out.println("Usage: java Caesar (-d | -e) key"); System.exit(1); } } }
Here is the result of an initial run of the program. First is the message file (a quotation for Ecclesiastes), followed by encryption by the key 3, and then by encryption followed by decryption (both using the same key), showing that the original message results. An simple analysis of the ciphertext would show a distribution of letters that would immediately lead to breaking the code. Notice also that the plaintext and ciphertext both end in double letters (ll and oo).
% 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.

% java Caesar -e 3 < 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 Caesar -e 3 < message.text | java Caesar -d 3
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 decrypted plaintext both have all the original punctuation characters, making it even easier to break the system. A more reasonable system would drop all such punctuation characters from the ciphertext. The one must break the decrypted ciphertext into separate words -- a task that is not hard for English. Here is a run of the program that has been altered to discard all characters except for lower-case letters. The final version of the message shows the words alternating as black and red.
% java Caesar2 -e 3 < message.text
luhwxuqhgdqgvdzxqghuwkhvxqwkdwwkhudfhlvqrwwrwkhvzliwqruwkhedwwohwrwkhvwurqjqhlwkhubhweuhdgwrwkhzlvhqrubhwulfkhvwrphqrixqghuvwdqglqjqrubhwidyrxuwrphqrivnlooexwwlphdqgfkdqfhkdsshqhwkwrwkhpdoo 

% java Caesar2 -e 3 < message.text | java Caesar2 -d 3
ireturnedandsawunderthesunthattheraceisnottotheswiftnorthebattletothestrongneitheryetbreadtothewisenoryetrichestomenofunderstandingnoryetfavourtomenofskillbuttimeandchancehappenethtothemall


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