Introduction
The trifid cipher java extends the bifid cipher from two dimensions to three, producing a cipher that is significantly harder to break while still being pen and paper friendly. It was invented in 1901 by the French cryptographer Felix Marie Delastelle, who also invented the bifid and four square ciphers. The trifid cipher java tutorial in this post walks through the construction of the 3 by 3 by 3 cube, the three-digit coordinate encoding, and the transposition stage that scrambles the coordinates.
The trifid cipher is interesting because it operates on three-digit coordinates instead of two-digit coordinates. Each plaintext letter is split into three digits (one for the layer, one for the row, one for the column of a 3 by 3 by 3 cube), and the digits are then transposed across multiple letters. This extended transposition is what makes the trifid cipher stronger than the bifid cipher.
What is the Trifid Cipher?
The trifid cipher is a fractionating transposition cipher. The plaintext alphabet is arranged in a 3 by 3 by 3 cube, which holds 27 symbols (the 26 letters A to Z plus a placeholder for the 27th cell, often a plus sign). Each plaintext letter is encoded as a three-digit coordinate consisting of its layer, row, and column in the cube. The coordinates of all plaintext letters are then written as three rows (one for layers, one for rows, one for columns), and the rows are concatenated and split into groups of three to produce the ciphertext coordinates.
Compared to the bifid cipher, the trifid cipher uses three digits per letter instead of two, which means the transposition stage mixes three plaintext letters into each ciphertext letter. Compared to the ADFGVX cipher, the trifid cipher uses a 3D cube instead of a 2D grid, which gives a different fractionation structure.
The trifid cipher is a monoalphabetic polygraphic cipher. The same plaintext letter always produces the same ciphertext letter at the same position, but the mapping depends on the surrounding letters because of the transposition stage.
How the Trifid Cipher Works Step by Step
Step 1: Build the 3 by 3 by 3 cube from a keyword. We use KEYWORD as the keyword. The mixed alphabet is KEYWORDABCFGHIJLMNPQSTUVXZ+ (the plus sign is the 27th symbol, used as a placeholder for non-letter characters). The cube is arranged in three layers, each layer being a 3 by 3 grid.
Step 2: Encode the plaintext. We use HELLO as the plaintext. H is at layer 0, row 2, column 2 (0-indexed), so its coordinate is 022. E is at layer 0, row 0, column 2, coordinate 002. L is at layer 1, row 1, column 0, coordinate 110. L is 110. O is at layer 0, row 1, column 2, coordinate 012. The plaintext coordinates are 022, 002, 110, 110, 012.
Step 3: Write the coordinates as three rows. The first row contains all the layer digits: 0 0 1 1 0. The second row contains all the row digits: 2 0 1 1 1. The third row contains all the column digits: 2 2 0 0 2. Concatenate the rows: 00110 20111 22002.
Step 4: Split the concatenated string into groups of three. The first group is 001, the second is 102, the third is 011, the fourth is 122, the fifth is 002. Each group of three digits is a coordinate in the cube, and the corresponding letter is the ciphertext letter.
Step 5: Look up each ciphertext coordinate in the cube to produce the ciphertext letters.
Java Program for Trifid Cipher
import java.util.LinkedHashSet;
import java.util.Set;
public class TrifidCipher {
private final char[][][] cube = new char[3][3][3];
private final int period; // group size for transposition
public TrifidCipher(String keyword, int period) {
this.period = period;
buildCube(keyword);
}
private void buildCube(String keyword) {
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);
seen.add('+'); // 27th symbol placeholder
int i = 0;
for (Character c : seen) {
cube[i / 9][(i % 9) / 3][(i % 9) % 3] = c;
i++;
if (i == 27) break;
}
}
private int[] coordOf(char ch) {
ch = (ch >= 'a' && ch <= 'z') ? (char) (ch - 32) : ch;
for (int l = 0; l < 3; l++) {
for (int r = 0; r < 3; r++) {
for (int c = 0; c < 3; c++) {
if (cube[l][r][c] == ch) return new int[]{l, r, c};
}
}
}
throw new IllegalArgumentException("Char not in cube: " + ch);
}
private char charAt(int l, int r, int c) {
return cube[l][r][c];
}
public String encrypt(String plain) {
plain = plain.toUpperCase().replaceAll("[^A-Z]", "");
StringBuilder layers = new StringBuilder();
StringBuilder rows = new StringBuilder();
StringBuilder cols = new StringBuilder();
for (char ch : plain.toCharArray()) {
int[] rc = coordOf(ch);
layers.append(rc[0]);
rows.append(rc[1]);
cols.append(rc[2]);
}
String combined = layers.toString() + rows.toString() + cols.toString();
// split into groups of `period` and recombine by position
StringBuilder result = new StringBuilder();
int total = combined.length();
int groupCount = (total + period - 1) / period;
for (int g = 0; g < groupCount; g++) {
for (int i = 0; i < period; i++) {
int pos = g + i * groupCount;
if (pos < total) {
result.append(combined.charAt(pos));
}
}
}
// now split into groups of 3 and look up cube
StringBuilder cipher = new StringBuilder();
for (int i = 0; i + 2 < result.length(); i += 3) {
int l = result.charAt(i) - '0';
int r = result.charAt(i + 1) - '0';
int c = result.charAt(i + 2) - '0';
cipher.append(charAt(l, r, c));
}
return cipher.toString();
}
public String decrypt(String cipher) {
cipher = cipher.toUpperCase().replaceAll("[^A-Z]", "");
// convert each cipher char to 3 digits
StringBuilder digits = new StringBuilder();
for (char ch : cipher.toCharArray()) {
int[] rc = coordOf(ch);
digits.append(rc[0]).append(rc[1]).append(rc[2]);
}
// reverse the period transposition
int total = digits.length();
int groupCount = (total + period - 1) / period;
int remainder = total % period;
StringBuilder combined = new StringBuilder();
combined.setLength(total);
int idx = 0;
for (int g = 0; g < groupCount; g++) {
for (int i = 0; i < period; i++) {
int pos = g + i * groupCount;
if (pos < total) {
combined.setCharAt(pos, digits.charAt(idx++));
}
}
}
String c = combined.toString();
int n = c.length() / 3;
StringBuilder plain = new StringBuilder();
for (int i = 0; i < n; i++) {
int l = c.charAt(i) - '0';
int r = c.charAt(n + i) - '0';
int col = c.charAt(2 * n + i) - '0';
plain.append(charAt(l, r, col));
}
return plain.toString();
}
public static void main(String[] args) {
TrifidCipher tc = new TrifidCipher("KEYWORD", 5);
String plain = "HELLO";
String cipher = tc.encrypt(plain);
String back = tc.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 period. The period controls the group size for the transposition stage and is typically set to 5 to 9. The buildCube method uses a LinkedHashSet to collect letters from the keyword first, then from the regular alphabet, plus a plus sign as the 27th symbol. The result is a 3 by 3 by 3 char array indexed by layer, row, and column.
The coordOf method scans the cube for a given letter and returns its layer, row, and column as a three-element int array. The charAt method is the inverse: given a layer, row, and column, it returns the letter at that position.
The encrypt method first encodes each plaintext letter as a three-digit coordinate. It accumulates the layer digits, row digits, and column digits into three separate StringBuilders, then concatenates them. The concatenated string is then split into groups of the period length, and the groups are recombined by position to perform the transposition.
The transposed string is then split into groups of three, each group being a coordinate in the cube, and the corresponding letters are looked up to produce the ciphertext.
The decrypt method reverses the process. It first converts each ciphertext letter to its three-digit coordinate, reverses the period transposition, and then splits the recovered digit string into three equal parts (layers, rows, columns) and recombines them into plaintext letters.
Sample Input and Output
Keyword: KEYWORD Period : 5 Plain : HELLO Cipher: (output of the program) Back : HELLO
The plaintext HELLO is encoded as the coordinates 022, 002, 110, 110, 012. The layer digits 00110, row digits 20111, and column digits 22002 are concatenated to form 001102011122002. The transposition stage with period 5 produces a new ordering of the digits, which is then split into groups of three to produce ciphertext coordinates. The decrypted output matches the original plaintext exactly.
Common Mistakes to Avoid
First, choosing a period of 1. A period of 1 means each plaintext letter is processed independently, which makes the trifid cipher degenerate to a simple Polybius square lookup. The period should be at least 5 to mix multiple plaintext letters into each ciphertext letter.
Second, forgetting the 27th symbol. The 3 by 3 by 3 cube holds 27 cells, but the alphabet has only 26 letters. You must add a placeholder (commonly a plus sign or a space) to fill the 27th cell, or the cube construction will fail.
Third, reversing the transposition incorrectly in decrypt. The transposition in encrypt groups digits by period and reorders them by position. The decrypt method must reverse this reordering exactly, or the round trip will fail.
Fourth, using a keyword with duplicate letters. The LinkedHashSet deduplicates, but if you skip this step, the cube will have fewer than 27 distinct symbols, and some plaintext letters will not have a coordinate.
Real-World Applications
The trifid cipher is not used in production today. Its security is weak by modern standards because it is a monoalphabetic polygraphic cipher that can be broken with enough ciphertext using higher order frequency analysis.
However, the trifid cipher is a useful teaching example because it generalizes the bifid cipher from two dimensions to three. The same principle extends to higher dimensions, although the practical value diminishes because the cube becomes too large to operate by hand.
The trifid cipher also demonstrates the principle of fractionation followed by transposition. Each plaintext letter is split into three digits, the digits are transposed across multiple letters, and the transposed digits are reassembled into ciphertext letters. This is the same pattern used by the ADFGVX cipher, but with three digits per letter instead of two.
In capture the flag events, the trifid cipher is sometimes used as a puzzle that requires the solver to recognize the three-digit encoding and the period transposition. The hint is usually a ciphertext that is exactly the same length as the plaintext (a property of the trifid cipher that distinguishes it from ciphers that change the length).
The trifid cipher is also a useful demonstration of the principle of confusion and diffusion. The substitution (cube lookup) provides confusion, and the transposition provides diffusion. Modern block ciphers use the same two principles, with multiple rounds of substitution and permutation to achieve strong security.
Conclusion
The trifid cipher is a fractionating transposition cipher that uses a 3 by 3 by 3 cube and a period based transposition. We built the cube from a keyword, encoded each plaintext letter as a three-digit coordinate, transposed the coordinates across multiple letters, and reversed the process for decryption. Next you should study the bifid cipher (which uses a 5 by 5 grid and two-digit coordinates), the four square cipher (which uses four 5 by 5 grids), and the ADFGVX cipher (which uses a 6 by 6 grid and a columnar transposition).
Comments
Comments
Post a Comment