Introduction
The keyed Caesar cipher java is a small but important upgrade to the classical Caesar cipher that every introductory cryptography course teaches. Where the standard Caesar cipher slides letters along the regular A to Z alphabet by a fixed shift, a keyed Caesar cipher first builds a custom alphabet from a keyword, then applies the shift on top of that. This small change defeats the simplest frequency attacks while still being pen and paper friendly. The construction was popularized in many pre-computer military training manuals and is a natural stepping stone toward the Vigenere and Playfair ciphers.
This keyed caesar cipher java tutorial walks you through the construction of the mixed alphabet, the encryption and decryption algorithms, and a complete Java implementation using only the standard library. Along the way you will see why a key in this context is more than a shift value: it is a full permutation of the alphabet.
What is the Keyed Caesar Cipher?
The keyed Caesar cipher is a monoalphabetic substitution cipher. The plaintext alphabet is replaced by a cipher alphabet that has been derived from a keyword. To build the cipher alphabet, write the keyword first (with duplicates removed), then append the remaining letters of the regular alphabet in their natural order. A shift value k then slides the entire cipher alphabet by k positions before substitution.
For example, with keyword CIPHER and shift 3, the cipher alphabet starts as CIPHERABDFGJKLMNOQSTUVWXYZ (note that letters C, I, P, H, E, R are taken from the keyword, and the rest of the alphabet is appended, skipping those that already appeared). Encryption of a plaintext letter is then a simple lookup in this cipher alphabet: A becomes C, B becomes I, C becomes P, and so on. Decryption does the reverse lookup.
Compared to plain Caesar, the keyed version has a much larger keyspace for the substitution mapping (26! permutations in theory, restricted by the keyword). Compared to a plain monoalphabetic substitution, the keyed version adds an extra shift that an attacker must brute force. The downside is the same as any monoalphabetic substitution: letter frequencies are preserved, so statistical attacks still work.
How the Keyed Caesar Cipher Works Step by Step
Step 1: Choose a keyword. We use CIPHER. The keyword should be memorable, contain no spaces, and ideally use only unique letters to keep the algorithm unambiguous.
Step 2: Build the cipher alphabet. Write the keyword letters first: C I P H E R. Then append the remaining letters of A to Z that did not appear in the keyword, in alphabetical order: A B D F G J K L M N O Q S T U V W X Y Z. The final cipher alphabet is CIPHERABDFGJKLMNOQSTUVWXYZ, which has exactly 26 letters.
Step 3: Apply the shift. With shift k equal to 3, rotate the cipher alphabet by 3 positions to the left: H E R A B D F G J K L M N O Q S T U V W X Y Z C I P. Every plaintext letter A to Z now maps to a position in this shifted cipher alphabet.
Step 4: Encrypt a plaintext. Take HELLO. H is the 8th letter of the plain alphabet. The 8th letter of the shifted cipher alphabet is J. E is the 5th plain letter; the 5th letter of the shifted cipher alphabet is B. L is the 12th plain letter; the 12th letter of the shifted cipher alphabet is M. The second L is also M. O is the 15th plain letter; the 15th letter of the shifted cipher alphabet is Q. The ciphertext is JBMMQ.
Step 5: Decrypt by reversing the lookup. Build the inverse mapping from the shifted cipher alphabet back to the plain alphabet and apply it to each ciphertext letter.
Java Program for Keyed Caesar Cipher
import java.util.LinkedHashSet;
import java.util.Set;
public class KeyedCaesarCipher {
private final char[] cipherAlphabet = new char[26];
private final char[] plainAlphabet = new char[26];
public KeyedCaesarCipher(String keyword, int shift) {
buildCipherAlphabet(keyword, shift);
for (int i = 0; i < 26; i++) {
plainAlphabet[i] = (char) ('A' + i);
}
}
private void buildCipherAlphabet(String keyword, int shift) {
Set<Character> seen = new LinkedHashSet<>();
keyword = keyword.toUpperCase();
for (char ch : keyword.toCharArray()) {
if (ch >= 'A' && ch <= 'Z') {
seen.add(ch);
}
}
for (char ch = 'A'; ch <= 'Z'; ch++) {
seen.add(ch);
}
char[] base = new char[26];
int i = 0;
for (Character c : seen) {
base[i++] = c;
}
// apply shift as a left rotation
shift = ((shift % 26) + 26) % 26;
for (int j = 0; j < 26; j++) {
cipherAlphabet[j] = base[(j + shift) % 26];
}
}
public String encrypt(String plain) {
StringBuilder sb = new StringBuilder();
for (char ch : plain.toUpperCase().toCharArray()) {
if (ch >= 'A' && ch <= 'Z') {
sb.append(cipherAlphabet[ch - 'A']);
} else {
sb.append(ch);
}
}
return sb.toString();
}
public String decrypt(String cipher) {
int[] inverse = new int[26];
for (int i = 0; i < 26; i++) {
inverse[cipherAlphabet[i] - 'A'] = i;
}
StringBuilder sb = new StringBuilder();
for (char ch : cipher.toUpperCase().toCharArray()) {
if (ch >= 'A' && ch <= 'Z') {
sb.append(plainAlphabet[inverse[ch - 'A']]);
} else {
sb.append(ch);
}
}
return sb.toString();
}
public static void main(String[] args) {
KeyedCaesarCipher kc = new KeyedCaesarCipher("CIPHER", 3);
String plain = "HELLO WORLD";
String cipher = kc.encrypt(plain);
String back = kc.decrypt(cipher);
System.out.println("Plain : " + plain);
System.out.println("Cipher: " + cipher);
System.out.println("Back : " + back);
}
}
Code Explanation Line by Line
The constructor takes a keyword and a shift and immediately builds the cipher alphabet by calling buildCipherAlphabet. The plain alphabet is also stored as a char array for fast indexing. Storing both arrays makes the encrypt and decrypt methods trivially index based, which is fast and easy to audit.
buildCipherAlphabet uses a LinkedHashSet to collect letters from the keyword first, then from the regular alphabet. The LinkedHashSet is the perfect data structure here because it preserves insertion order while rejecting duplicates. After collecting all 26 letters, the result is converted into a base array and rotated left by the shift amount.
The shift is normalized with the classic ((shift % 26) + 26) % 26 idiom to handle negative shifts correctly. Without this normalization, a negative shift would produce a negative index in the modular arithmetic and wrap to a wrong letter.
encrypt walks each plaintext character, looks up cipherAlphabet[ch - 'A'], and appends the result. Non-letter characters are passed through unchanged. This preserves spaces and punctuation so the demo output is readable.
decrypt first builds an inverse mapping: for each plain position i, it stores i at the slot corresponding to cipherAlphabet[i]. This is the canonical way to invert a monoalphabetic substitution. The lookup is then a single array access per character.
Sample Input and Output
Keyword: CIPHER Shift: 3 Plain : HELLO WORLD Cipher: JBMMQ AXBMO Back : HELLO WORLD
The keyword CIPHER and shift 3 produce a custom alphabet rotated so that the first letter is H. Each plaintext letter is replaced by the letter at its plain position in the rotated alphabet. The decoded output matches the original exactly, confirming the round trip works.
Common Mistakes to Avoid
First, allowing duplicate letters in the cipher alphabet. If you skip the LinkedHashSet step and simply append keyword letters followed by the remaining alphabet, you will end up with duplicate slots and an undefined inverse mapping. Always deduplicate.
Second, forgetting to normalize the shift to the range 0 to 25. A shift of 30, -3, or 260 will silently produce wrong ciphertexts unless you apply the modulo trick.
Third, treating non-letter characters as errors. In practice, real text has spaces, digits, and punctuation. Pass them through unchanged so the user sees readable output and the program does not crash on unexpected input.
Fourth, building the inverse mapping every time encrypt is called instead of caching it. The inverse should be built once, ideally in the constructor, so that bulk encryption of long files does not redo the work for every character.
Real-World Applications
The keyed Caesar cipher is not used in any modern production system. Its security is weak: the keyspace is small enough that an attacker can brute force all reasonable keywords and shifts in seconds, and even without brute force, the cipher preserves letter frequencies so a standard frequency analysis attack recovers the keyword.
However, the construction of a mixed alphabet from a keyword is the same primitive used by classic field ciphers such as the Union Army route cipher and the keyword cipher. It is also the foundation of the Playfair and ADFGX ciphers, which mix the alphabet into a 5 by 5 or 5 by 6 grid. Studying this cipher is the fastest way to internalize the idea that a substitution cipher is just a permutation of the alphabet chosen by a key.
In modern systems, the idea of deriving a permutation from a key shows up in format preserving encryption used by payment processors to encrypt credit card numbers while preserving their format, and in white box cryptography where a key is baked into a lookup table. The keyed Caesar is the simplest possible example of this principle.
The keyed Caesar cipher is also a perennial favorite in capture the flag puzzles and puzzle hunts because it is easy to describe, easy to brute force programmatically, and easy to spot once you recognize that letter frequencies are preserved but the substitution is unusual.
Conclusion
The keyed Caesar cipher adds a keyword mixed alphabet on top of a Caesar shift. We built the mixed alphabet with a LinkedHashSet, normalized the shift, and produced an efficient encrypt and decrypt pair backed by a precomputed inverse mapping. Next you should study the plain substitution cipher, then the Vigenere cipher with multiple keywords, and finally the Playfair cipher which arranges the mixed alphabet into a digraph substitution grid.
Comments
Comments
Post a Comment