ADFGVX cipher: Difference between revisions
Content added Content deleted
VincentARM (talk | contribs) mNo edit summary |
(New post) |
||
Line 1,945: | Line 1,945: | ||
(Technically, we do not need the Polybius square to recover the spaces, but it's passed as an argument here for symmetry.) |
(Technically, we do not need the Polybius square to recover the spaces, but it's passed as an argument here for symmetry.) |
||
=={{header|Java}}== |
|||
<syntaxhighlight lang="java"> |
|||
import java.io.IOException; |
|||
import java.nio.file.Files; |
|||
import java.nio.file.Path; |
|||
import java.util.Arrays; |
|||
import java.util.Collections; |
|||
import java.util.List; |
|||
import java.util.stream.Collectors; |
|||
public final class ADFGVXCipher { |
|||
public static void main(String[] args) throws IOException { |
|||
final char[][] polybius = initialisePolybiusSquare(); |
|||
System.out.println("The 6 x 6 Polybius square:"); |
|||
System.out.println(" | A D F G V X"); |
|||
System.out.println("--------------"); |
|||
for ( int row = 0; row < 6; row++ ) { |
|||
System.out.print(ADFGVX.charAt(row) + "|"); |
|||
for ( int column = 0; column < 6; column++ ) { |
|||
System.out.print(" " + polybius[row][column]); |
|||
} |
|||
System.out.println(); |
|||
} |
|||
System.out.println(); |
|||
final String key = createKey(9); |
|||
System.out.println("The key is " + key); |
|||
System.out.println(); |
|||
final String plainText = "ATTACKAT1200AM"; |
|||
System.out.println("Plaintext: " + plainText); |
|||
System.out.println(); |
|||
final String encryptedText = encrypt(plainText, polybius, key); |
|||
System.out.println("Encrypted: " + encryptedText); |
|||
System.out.println(); |
|||
final String decryptedText = decrypt(encryptedText, polybius, key); |
|||
System.out.println("Decrypted: " + decryptedText); |
|||
} |
|||
private static String encrypt(String plainText, char[][] polybius, String key) { |
|||
String code = ""; |
|||
for ( char ch : plainText.toCharArray() ) { |
|||
for ( int row = 0; row < 6; row++ ) { |
|||
for ( int column = 0; column < 6; column++ ) { |
|||
if ( polybius[row][column] == ch ) { |
|||
code += ADFGVX.charAt(row) + "" + ADFGVX.charAt(column); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
String encrypted = ""; |
|||
for ( char ch : key.toCharArray() ) { |
|||
for ( int i = key.indexOf(ch); i < code.length(); i += key.length() ) { |
|||
encrypted += code.charAt(i); |
|||
} |
|||
encrypted += " "; |
|||
} |
|||
return encrypted; |
|||
} |
|||
private static String decrypt(String encryptedText, char[][] polybius, String key) { |
|||
final int codeSize = encryptedText.replace(" ", "").length(); |
|||
String code = ""; |
|||
for ( int i = 0; code.length() < codeSize; i++ ) { |
|||
for ( String block : encryptedText.split(" ") ) { |
|||
if ( code.length() < codeSize ) { |
|||
code += block.charAt(i); |
|||
} |
|||
} |
|||
} |
|||
String plainText = ""; |
|||
for ( int i = 0; i < codeSize - 1; i += 2 ) { |
|||
int row = ADFGVX.indexOf(code.substring(i, i + 1)); |
|||
int column = ADFGVX.indexOf(code.substring(i + 1, i + 2)); |
|||
plainText += polybius[row][column]; |
|||
} |
|||
return plainText; |
|||
} |
|||
// Create a key using a word from "unixdict.txt" |
|||
private static String createKey(int size) throws IOException { |
|||
if ( size < 7 || size > 12 ) { |
|||
throw new AssertionError("Key should contain between 7 and 12 letters, both inclusive."); |
|||
} |
|||
List<String> candidates = Files.lines(Path.of("unixdict.txt")) |
|||
.filter( word -> word.length() == size ) |
|||
.filter( word -> word.chars().distinct().count() == word.length() ) |
|||
.filter( word -> word.chars().allMatch(Character::isLetterOrDigit) ) |
|||
.collect(Collectors.toList()); |
|||
Collections.shuffle(candidates); |
|||
return candidates.get(0).toUpperCase(); |
|||
} |
|||
private static char[][] initialisePolybiusSquare() { |
|||
List<String> letters = Arrays.asList("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".split("")); |
|||
Collections.shuffle(letters); |
|||
char[][] result = new char[6][6]; |
|||
for ( int row = 0; row < 6; row++ ) { |
|||
for ( int column = 0; column < 6; column++ ) { |
|||
result[row][column] = letters.get(6 * row + column).charAt(0); |
|||
} |
|||
} |
|||
return result; |
|||
} |
|||
private static final String ADFGVX = "ADFGVX"; |
|||
} |
|||
</syntaxhighlight> |
|||
{{ out }} |
|||
<pre> |
|||
The 6 x 6 Polybius square: |
|||
| A D F G V X |
|||
-------------- |
|||
A| 2 K 4 Q 9 8 |
|||
D| W C I M V A |
|||
F| 5 S 0 Y B D |
|||
G| F T O U J E |
|||
V| 6 1 R X 3 G |
|||
X| H L Z P 7 N |
|||
The key is DISHWATER |
|||
Plaintext: ATTACKAT1200AM |
|||
Encrypted: DDAG XAA GDF DDF GXF DGF DDD XVX DDD |
|||
Decrypted: ATTACKAT1200AM |
|||
</pre> |
|||
=={{header|Julia}}== |
=={{header|Julia}}== |