Files
Prog_1/Enigma/Shell.java
Felix Steghofer 3db4f94e6a init
2022-12-04 01:25:28 +01:00

252 lines
8.6 KiB
Java

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
/**
* Main Class for interaction with the user.
*
*/
public final class Shell {
/**
* number of arguments / rotor.
*/
private static final int ROTORARGS = 3;
/**
* Patchboard-permutation.
*/
private static final int[] PATCHBOARDPERMU = new int[] {9, 22, 20, 11, 2, 12
, 13, 14, 7, 15, 16, 25, 24, 23, 8, 17, 0, 3, 10, 4, 6, 21, 1, 19
, 18, 5};
/**
* Reflector- permutation.
*/
private static final int[] REFLECTORPERMU = new int[] {8, 12, 4, 19, 2, 6, 5
, 17, 0, 24, 18, 16, 1, 25, 23, 22, 11, 7, 10, 3, 21, 20, 15, 14
, 9, 13};
/**
* Amount of Symbols the alphabet uses.
*/
private static int symbols = PATCHBOARDPERMU.length;
private Shell() { }
/**
* Convert char-Array to Enigma-permutation-array.
* @param charArray char-array to convert
* @return Enigma-compatible <code>permutation array</code>
*/
private static int[] convertCharInt(final char[] charArray) {
int[] intArray = new int[charArray.length];
for (int i = 0; i < charArray.length; i++) {
intArray[i] = (charArray[i] - 65);
}
return intArray;
}
/**
* Convert Enigma-int to char.
* @param i Enigma-int
* @return <code>char</code>
*/
private static char convertIntChar(final int i) {
return (char) (i + 65);
}
/**
* Checks if every Parameter for a Enigma exists.
* @param stringArray Array of all programm parameters
* @return <code>true</code> if right number of parameters are given<br />
* <code>false</code> if wrong number of parameters or parameters
* are zero
*/
private static boolean checkArgsLength(final String[] stringArray) {
return stringArray.length % ROTORARGS == 0 && stringArray.length != 0;
}
/**
* Extracts the Permutation-Array Elements out of the Arguments
* given by the User. <br /> Every third Element is a Permutation-Array.
* Furthermore, the lengths of the Array is checked to handle faults.
* @param stringAr the <code>String</code> entered by the user.
* @return <code>Permutation-Array[][]</code> for every Rotor as a
* char-array or<br /><code>null</code> if any error occurs.
*/
private static int[][] extractPermuArray(final String[] stringAr) {
int[][] intArray = new int[(stringAr.length / ROTORARGS)]
[Shell.symbols];
for (int i = 0; i < (stringAr.length) / ROTORARGS; i++) {
if (stringAr[(i * ROTORARGS)].length() == Shell.symbols) {
intArray[i] = convertCharInt(
stringAr[(i * ROTORARGS)].toCharArray());
} else { return null; }
}
return intArray;
}
/**
* Extract the tick-Positions out of string-array into a int-array.
* @param stringAr All Arguments committed to the Programm
* @return <code>int-array</code> with rotors tick-positions <br />
* or <code>null</code> if tick-positition has more then
* one character
*/
private static int[] extractTickPosArray(final String[] stringAr) {
int[] intArray = new int[(stringAr.length / ROTORARGS)];
for (int i = 0; i < (stringAr.length / ROTORARGS); i++) {
if (stringAr[1 + (i * ROTORARGS)].toCharArray().length == 1) {
intArray[i] = stringAr[1 + (i * ROTORARGS)].charAt(0) - 65;
} else { return null; }
}
return intArray;
}
/**
* Extract the initial-Positions out of string-array into a int-array.
* @param stringAr All Arguments committed to the Programm
* @return <code>int-array</code> with rotors initial-positions <br />
* or <code>null</code> if initial-positition has more then
* one character
*/
private static int[] extractInitialPosArray(final String[] stringAr) {
int[] intArray = new int[(stringAr.length / ROTORARGS)];
for (int i = 0; i < (stringAr.length / ROTORARGS); i++) {
if (stringAr[2 + (i * ROTORARGS)].toCharArray().length == 1) {
intArray[i] = stringAr[2 + (i * ROTORARGS)].charAt(0) - 65;
} else { return null; }
}
return intArray;
}
/**
* Checks if char is a capital-Letter.
* @param ch Character
* @return <code>true</code> <br >/
* or <code>false</code>
*/
private static boolean isEnigmaChar(final int ch) {
if (ch < 0 || ch >= Shell.symbols) {
return false;
}
return true;
}
/**
* Checks if char-array is a capital-Letter-array.
* @param ch Character-array
* @return <code>true</code> <br >/
* or <code>false</code>
*/
private static boolean isEnigmaCharArray(final int[] ch) {
for (int i = 0; i < ch.length; i++) {
if (!isEnigmaChar(ch[i])) {
return false;
}
}
return true;
}
/**
* Checks if char-array-array is a capital-Letter-array-array.
* @param ch Character-array-array
* @return <code>true</code> <br >/
* or <code>false</code>
*/
private static boolean isEnigmaCharArray(final int[][] ch) {
for (int i = 0; i < ch.length; i++) {
if (!isEnigmaCharArray(ch[i])) {
return false;
}
}
return true;
}
/**
* Checks if a permutation contains a char twice.
* @param permu Permutation
* @return <code>true</code> if duplicate char is found<br />
* <code>false</code> if chars are unique
*/
private static boolean hasDuplicateChar(final int[][] permu) {
boolean[][] foo = new boolean[permu.length][permu[0].length];
int i;
int j;
for (i = 0; i < permu.length; i++) {
for (j = 0; j < permu[i].length; j++) {
if (foo[i][permu[i][j]]) {
return true;
} else {
foo[i][permu[i][j]] = true;
}
}
}
return false;
}
/**
* Main method for the Enigma-Simulation.
* @param args All parameter given to the Shell
* @throws IOException IOException
*/
public static void main(final String[] args) throws IOException {
int[][] permu = new int[(args.length / ROTORARGS)][Shell.symbols];
int[] tickPos = new int[(args.length / ROTORARGS)];
int[] initialPos = new int[(args.length / ROTORARGS)];
Enigma myEnigma;
if (checkArgsLength(args)) {
if (extractPermuArray(args) != null) {
permu = extractPermuArray(args);
} else {
System.out.println("Error! Wrong Permutation!");
return;
}
if (extractTickPosArray(args) != null) {
tickPos = extractTickPosArray(args);
} else {
System.out.println("Error! wrong Tick Position!");
return;
}
if (extractInitialPosArray(args) != null) {
initialPos = extractInitialPosArray(args);
} else {
System.out.println("Error! wrong initial Position!");
return;
}
} else {
System.out.println("Error: wrong number of Arguments");
return;
}
//Check if only Capital Letters are used
if (!isEnigmaCharArray(permu) || !isEnigmaCharArray(tickPos)
|| !isEnigmaCharArray(initialPos)) {
System.out.print("Error! wrong character in config");
return;
}
if (hasDuplicateChar(extractPermuArray(args))) {
System.out.println("Error! Duplicate char in Permutation");
}
BufferedReader br =
new BufferedReader(new InputStreamReader(System.in));
myEnigma = new Enigma(tickPos, initialPos, permu, PATCHBOARDPERMU
, REFLECTORPERMU);
while (true) {
String stdinp = br.readLine();
if (stdinp.equals("")) {
return;
}
int[] ciphertxt = convertCharInt(stdinp.toCharArray());
if (!isEnigmaCharArray(ciphertxt)) {
System.out.print("Error! Wrong input");
return;
}
for (int i = 0; i < ciphertxt.length; i++) {
System.out.print(convertIntChar(myEnigma.encode(ciphertxt[i])));
}
System.out.println();
}
}
}