From 9b8d4f15e1ce3782e70aeaba9d6785793efa703c Mon Sep 17 00:00:00 2001 From: Matthew Ellison Date: Wed, 23 Feb 2022 21:52:03 +0000 Subject: [PATCH 1/3] Created Beaufort cipher --- .../monoSubstitution/TestBeaufort.java | 407 ++++++++++++++++++ 1 file changed, 407 insertions(+) create mode 100644 src/test/java/com/mattrixwv/CipherStreamJava/monoSubstitution/TestBeaufort.java diff --git a/src/test/java/com/mattrixwv/CipherStreamJava/monoSubstitution/TestBeaufort.java b/src/test/java/com/mattrixwv/CipherStreamJava/monoSubstitution/TestBeaufort.java new file mode 100644 index 0000000..59de9c0 --- /dev/null +++ b/src/test/java/com/mattrixwv/CipherStreamJava/monoSubstitution/TestBeaufort.java @@ -0,0 +1,407 @@ +//CipherStreamJava/src/test/java/com/mattrixwv/CipherStreamJava/monoSubstitution/TestBeaufort.java +//Mattrixwv +// Created: 02-23-22 +//Modified: 02-23-22 +package com.mattrixwv.CipherStreamJava.monoSubstitution; + + +import static org.junit.Assert.assertEquals; + +import com.mattrixwv.CipherStreamJava.exceptions.InvalidInputException; +import com.mattrixwv.CipherStreamJava.exceptions.InvalidKeywordException; + +import org.junit.Test; + + +public class TestBeaufort{ + @Test + public void testEncode() throws InvalidKeywordException, InvalidInputException{ + Beaufort cipher = new Beaufort(true, true, true); + + //Test lowercase encoding + String inputString = "messagetoencode"; + String keyword = "keyword"; + String correctOutput = "yageolzrqujmdag"; + String output = cipher.encode(keyword, inputString); + assertEquals("Beaufort failed lowercase encoding.", correctOutput, output); + //Test uppercase encoding + inputString = "MESSAGETOENCODE"; + keyword = "keyword"; + correctOutput = "YAGEOLZRQUJMDAG"; + output = cipher.encode(keyword, inputString); + assertEquals("Beaufort failed uppercase encoding.", correctOutput, output); + + //Test whitespace encoding + inputString = "message to encode"; + keyword = "keyword"; + correctOutput = "yageolz rq ujmdag"; + output = cipher.encode(keyword, inputString); + assertEquals("Beaufort failed whitespace encoding.", correctOutput, output); + + //Test symbol encoding + inputString = "message*to+encode"; + keyword = "keyword"; + correctOutput = "yageolz*rq+ujmdag"; + output = cipher.encode(keyword, inputString); + assertEquals("Beaufort failed symbol encoding.", correctOutput, output); + + //Test mixed case, whitespace, symbol encoding + inputString = "Message to^encode"; + keyword = "keyword"; + correctOutput = "Yageolz rq^ujmdag"; + output = cipher.encode(keyword, inputString); + assertEquals("Beaufort failed mixed case, whitespace, symbol encoding.", correctOutput, output); + } + + @Test + public void testNoCapitalEncode() throws InvalidKeywordException, InvalidInputException{ + Beaufort cipher = new Beaufort(false, true, true); + + //Test lowercase encoding + String inputString = "messagetoencode"; + String keyword = "keyword"; + String correctOutput = "YAGEOLZRQUJMDAG"; + String output = cipher.encode(keyword, inputString); + assertEquals("Beaufort failed no capital lowercase encoding.", correctOutput, output); + //Test uppercase encoding + inputString = "MESSAGETOENCODE"; + keyword = "keyword"; + correctOutput = "YAGEOLZRQUJMDAG"; + output = cipher.encode(keyword, inputString); + assertEquals("Beaufort failed no capital uppercase encoding.", correctOutput, output); + + //Test whitespace encoding + inputString = "message to encode"; + keyword = "keyword"; + correctOutput = "YAGEOLZ RQ UJMDAG"; + output = cipher.encode(keyword, inputString); + assertEquals("Beaufort failed no capital whitespace encoding.", correctOutput, output); + + //Test symbol encoding + inputString = "message*to+encode"; + keyword = "keyword"; + correctOutput = "YAGEOLZ*RQ+UJMDAG"; + output = cipher.encode(keyword, inputString); + assertEquals("Beaufort failed no capital symbol encoding.", correctOutput, output); + + //Test mixed case, whitespace, symbol encoding + inputString = "Message to^encode"; + keyword = "keyword"; + correctOutput = "YAGEOLZ RQ^UJMDAG"; + output = cipher.encode(keyword, inputString); + assertEquals("Beaufort failed no capital mixed case, whitespace, symbol encoding.", correctOutput, output); + } + + @Test + public void testNoWhitespaceEncode() throws InvalidKeywordException, InvalidInputException{ + Beaufort cipher = new Beaufort(true, false, true); + + //Test lowercase encoding + String inputString = "messagetoencode"; + String keyword = "keyword"; + String correctOutput = "yageolzrqujmdag"; + String output = cipher.encode(keyword, inputString); + assertEquals("Beaufort failed no whitespace lowercase encoding.", correctOutput, output); + //Test uppercase encoding + inputString = "MESSAGETOENCODE"; + keyword = "keyword"; + correctOutput = "YAGEOLZRQUJMDAG"; + output = cipher.encode(keyword, inputString); + assertEquals("Beaufort failed no whitespace uppercase encoding.", correctOutput, output); + + //Test whitespace encoding + inputString = "message to encode"; + keyword = "keyword"; + correctOutput = "yageolzrqujmdag"; + output = cipher.encode(keyword, inputString); + assertEquals("Beaufort failed no whitespace whitespace encoding.", correctOutput, output); + + //Test symbol encoding + inputString = "message*to+encode"; + keyword = "keyword"; + correctOutput = "yageolz*rq+ujmdag"; + output = cipher.encode(keyword, inputString); + assertEquals("Beaufort failed no whitespace symbol encoding.", correctOutput, output); + + //Test mixed case, whitespace, symbol encoding + inputString = "Message to^encode"; + keyword = "keyword"; + correctOutput = "Yageolzrq^ujmdag"; + output = cipher.encode(keyword, inputString); + assertEquals("Beaufort failed no whitespace mixed case, whitespace, symbol encoding.", correctOutput, output); + } + + @Test + public void testNoSymbolEncode() throws InvalidKeywordException, InvalidInputException{ + Beaufort cipher = new Beaufort(true, true, false); + + //Test lowercase encoding + String inputString = "messagetoencode"; + String keyword = "keyword"; + String correctOutput = "yageolzrqujmdag"; + String output = cipher.encode(keyword, inputString); + assertEquals("Beaufort failed no symbol lowercase encoding.", correctOutput, output); + //Test uppercase encoding + inputString = "MESSAGETOENCODE"; + keyword = "keyword"; + correctOutput = "YAGEOLZRQUJMDAG"; + output = cipher.encode(keyword, inputString); + assertEquals("Beaufort failed no symbol uppercase encoding.", correctOutput, output); + + //Test whitespace encoding + inputString = "message to encode"; + keyword = "keyword"; + correctOutput = "yageolz rq ujmdag"; + output = cipher.encode(keyword, inputString); + assertEquals("Beaufort failed no symbol whitespace encoding.", correctOutput, output); + + //Test symbol encoding + inputString = "message*to+encode"; + keyword = "keyword"; + correctOutput = "yageolzrqujmdag"; + output = cipher.encode(keyword, inputString); + assertEquals("Beaufort failed no symbol symbol encoding.", correctOutput, output); + + //Test mixed case, whitespace, symbol encoding + inputString = "Message to^encode"; + keyword = "keyword"; + correctOutput = "Yageolz rqujmdag"; + output = cipher.encode(keyword, inputString); + assertEquals("Beaufort failed no symbol mixed case, whitespace, symbol encoding.", correctOutput, output); + } + + @Test + public void testNoCapitalwhitespaceSymbolEncode() throws InvalidKeywordException, InvalidInputException{ + Beaufort cipher = new Beaufort(false, false, false); + + //Test lowercase encoding + String inputString = "messagetoencode"; + String keyword = "keyword"; + String correctOutput = "YAGEOLZRQUJMDAG"; + String output = cipher.encode(keyword, inputString); + assertEquals("Beaufort failed secure lowercase encoding.", correctOutput, output); + //Test uppercase encoding + inputString = "MESSAGETOENCODE"; + keyword = "keyword"; + correctOutput = "YAGEOLZRQUJMDAG"; + output = cipher.encode(keyword, inputString); + assertEquals("Beaufort failed secure uppercase encoding.", correctOutput, output); + + //Test whitespace encoding + inputString = "message to encode"; + keyword = "keyword"; + correctOutput = "YAGEOLZRQUJMDAG"; + output = cipher.encode(keyword, inputString); + assertEquals("Beaufort failed secure whitespace encoding.", correctOutput, output); + + //Test symbol encoding + inputString = "message*to+encode"; + keyword = "keyword"; + correctOutput = "YAGEOLZRQUJMDAG"; + output = cipher.encode(keyword, inputString); + assertEquals("Beaufort failed secure symbol encoding.", correctOutput, output); + + //Test mixed case, whitespace, symbol encoding + inputString = "Message to^encode"; + keyword = "keyword"; + correctOutput = "YAGEOLZRQUJMDAG"; + output = cipher.encode(keyword, inputString); + assertEquals("Beaufort failed secure mixed case, whitespace, symbol encoding.", correctOutput, output); + } + + + @Test + public void testDecode() throws InvalidKeywordException, InvalidInputException{ + Beaufort cipher = new Beaufort(true, true, true); + + //Test lowercase decoding + String inputString = "yageolzrqujmdag"; + String keyword = "keyword"; + String correctOutput = "messagetoencode"; + String output = cipher.decode(keyword, inputString); + assertEquals("Beaufort failed lowercase decoding.", correctOutput, output); + //Test uppercase decoding + inputString = "YAGEOLZRQUJMDAG"; + keyword = "keyword"; + correctOutput = "MESSAGETOENCODE"; + output = cipher.decode(keyword, inputString); + assertEquals("Beaufort failed uppercase decoding.", correctOutput, output); + + //Test whitespace decoding + inputString = "yageolz rq ujmdag"; + keyword = "keyword"; + correctOutput = "message to encode"; + output = cipher.decode(keyword, inputString); + assertEquals("Beaufort failed whitespace decoding.", correctOutput, output); + + //Test symbol decoding + inputString = "yageolz*rq+ujmdag"; + keyword = "keyword"; + correctOutput = "message*to+encode"; + output = cipher.decode(keyword, inputString); + assertEquals("Beaufort failed symbol decoding.", correctOutput, output); + + //Test mixed case, whitespace, symbol decoding + inputString = "Yageolz rq^ujmdag"; + keyword = "keyword"; + correctOutput = "Message to^encode"; + output = cipher.decode(keyword, inputString); + assertEquals("Beaufort failed mixed case, whitespace, symbol decoding.", correctOutput, output); + } + + @Test + public void testNoCapitalDecode() throws InvalidKeywordException, InvalidInputException{ + Beaufort cipher = new Beaufort(false, true, true); + + //Test lowercase decoding + String inputString = "yageolzrqujmdag"; + String keyword = "keyword"; + String correctOutput = "MESSAGETOENCODE"; + String output = cipher.decode(keyword, inputString); + assertEquals("Beaufort failed no capital lowercase decoding.", correctOutput, output); + //Test uppercase decoding + inputString = "YAGEOLZRQUJMDAG"; + keyword = "keyword"; + correctOutput = "MESSAGETOENCODE"; + output = cipher.decode(keyword, inputString); + assertEquals("Beaufort failed no capital uppercase decoding.", correctOutput, output); + + //Test whitespace decoding + inputString = "yageolz rq ujmdag"; + keyword = "keyword"; + correctOutput = "MESSAGE TO ENCODE"; + output = cipher.decode(keyword, inputString); + assertEquals("Beaufort failed no capital whitespace decoding.", correctOutput, output); + + //Test symbol decoding + inputString = "yageolz*rq+ujmdag"; + keyword = "keyword"; + correctOutput = "MESSAGE*TO+ENCODE"; + output = cipher.decode(keyword, inputString); + assertEquals("Beaufort failed no capital symbol decoding.", correctOutput, output); + + //Test mixed case, whitespace, symbol decoding + inputString = "Yageolz rq^ujmdag"; + keyword = "keyword"; + correctOutput = "MESSAGE TO^ENCODE"; + output = cipher.decode(keyword, inputString); + assertEquals("Beaufort failed no capital mixed case, whitespace, symbol decoding.", correctOutput, output); + } + + @Test + public void testNoWhitespaceDecode() throws InvalidKeywordException, InvalidInputException{ + Beaufort cipher = new Beaufort(true, false, true); + + //Test lowercase decoding + String inputString = "yageolzrqujmdag"; + String keyword = "keyword"; + String correctOutput = "messagetoencode"; + String output = cipher.decode(keyword, inputString); + assertEquals("Beaufort failed no whitespace lowercase decoding.", correctOutput, output); + //Test uppercase decoding + inputString = "YAGEOLZRQUJMDAG"; + keyword = "keyword"; + correctOutput = "MESSAGETOENCODE"; + output = cipher.decode(keyword, inputString); + assertEquals("Beaufort failed no whitespace uppercase decoding.", correctOutput, output); + + //Test whitespace decoding + inputString = "yageolz rq ujmdag"; + keyword = "keyword"; + correctOutput = "messagetoencode"; + output = cipher.decode(keyword, inputString); + assertEquals("Beaufort failed no whitespace whitespace decoding.", correctOutput, output); + + //Test symbol decoding + inputString = "yageolz*rq+ujmdag"; + keyword = "keyword"; + correctOutput = "message*to+encode"; + output = cipher.decode(keyword, inputString); + assertEquals("Beaufort failed no whitespace symbol decoding.", correctOutput, output); + + //Test mixed case, whitespace, symbol decoding + inputString = "Yageolz rq^ujmdag"; + keyword = "keyword"; + correctOutput = "Messageto^encode"; + output = cipher.decode(keyword, inputString); + assertEquals("Beaufort failed no whitespace mixed case, whitespace, symbol decoding.", correctOutput, output); + } + + @Test + public void testNoSymbolDecode() throws InvalidKeywordException, InvalidInputException{ + Beaufort cipher = new Beaufort(true, true, false); + + //Test lowercase decoding + String inputString = "yageolzrqujmdag"; + String keyword = "keyword"; + String correctOutput = "messagetoencode"; + String output = cipher.decode(keyword, inputString); + assertEquals("Beaufort failed no symbol lowercase decoding.", correctOutput, output); + //Test uppercase decoding + inputString = "YAGEOLZRQUJMDAG"; + keyword = "keyword"; + correctOutput = "MESSAGETOENCODE"; + output = cipher.decode(keyword, inputString); + assertEquals("Beaufort failed no symbol uppercase decoding.", correctOutput, output); + + //Test whitespace decoding + inputString = "yageolz rq ujmdag"; + keyword = "keyword"; + correctOutput = "message to encode"; + output = cipher.decode(keyword, inputString); + assertEquals("Beaufort failed no symbol whitespace decoding.", correctOutput, output); + + //Test symbol decoding + inputString = "yageolz*rq+ujmdag"; + keyword = "keyword"; + correctOutput = "messagetoencode"; + output = cipher.decode(keyword, inputString); + assertEquals("Beaufort failed no symbol symbol decoding.", correctOutput, output); + + //Test mixed case, whitespace, symbol decoding + inputString = "Yageolz rq^ujmdag"; + keyword = "keyword"; + correctOutput = "Message toencode"; + output = cipher.decode(keyword, inputString); + assertEquals("Beaufort failed no symbol mixed case, whitespace, symbol decoding.", correctOutput, output); + } + + @Test + public void testNoCapitalWhitespaceSymbolDecode() throws InvalidKeywordException, InvalidInputException{ + Beaufort cipher = new Beaufort(false, false, false); + + //Test lowercase decoding + String inputString = "yageolzrqujmdag"; + String keyword = "keyword"; + String correctOutput = "MESSAGETOENCODE"; + String output = cipher.decode(keyword, inputString); + assertEquals("Beaufort failed secure lowercase decoding.", correctOutput, output); + //Test uppercase decoding + inputString = "YAGEOLZRQUJMDAG"; + keyword = "keyword"; + correctOutput = "MESSAGETOENCODE"; + output = cipher.decode(keyword, inputString); + assertEquals("Beaufort failed secure uppercase decoding.", correctOutput, output); + + //Test whitespace decoding + inputString = "yageolz rq ujmdag"; + keyword = "keyword"; + correctOutput = "MESSAGETOENCODE"; + output = cipher.decode(keyword, inputString); + assertEquals("Beaufort failed secure whitespace decoding.", correctOutput, output); + + //Test symbol decoding + inputString = "yageolz*rq+ujmdag"; + keyword = "keyword"; + correctOutput = "MESSAGETOENCODE"; + output = cipher.decode(keyword, inputString); + assertEquals("Beaufort failed secure symbol decoding.", correctOutput, output); + + //Test mixed case, whitespace, symbol decoding + inputString = "Yageolz rq^ujmdag"; + keyword = "keyword"; + correctOutput = "MESSAGETOENCODE"; + output = cipher.decode(keyword, inputString); + assertEquals("Beaufort failed secure mixed case, whitespace, symbol decoding.", correctOutput, output); + } +} From aabca431b2b04985da48ac7b84cd54b50e411a66 Mon Sep 17 00:00:00 2001 From: Matthew Ellison Date: Wed, 23 Feb 2022 22:05:33 +0000 Subject: [PATCH 2/3] Updated comments --- .../CipherStreamJava/combination/ADFGX.java | 58 +++++++++++++------ 1 file changed, 39 insertions(+), 19 deletions(-) diff --git a/src/main/java/com/mattrixwv/CipherStreamJava/combination/ADFGX.java b/src/main/java/com/mattrixwv/CipherStreamJava/combination/ADFGX.java index e5458ca..9a93b74 100644 --- a/src/main/java/com/mattrixwv/CipherStreamJava/combination/ADFGX.java +++ b/src/main/java/com/mattrixwv/CipherStreamJava/combination/ADFGX.java @@ -1,26 +1,29 @@ //CipherStreamJava/src/main/java/com/mattrixwv/CipherStreamJava/combination/ADFGX.java //Mattrixwv // Created: 01-25-22 -//Modified: 02-17-22 +//Modified: 02-23-22 package com.mattrixwv.CipherStreamJava.combination; + import com.mattrixwv.CipherStreamJava.exceptions.InvalidCharacterException; import com.mattrixwv.CipherStreamJava.exceptions.InvalidInputException; import com.mattrixwv.CipherStreamJava.exceptions.InvalidKeywordException; import com.mattrixwv.CipherStreamJava.polySubstitution.Columnar; import com.mattrixwv.CipherStreamJava.polySubstitution.PolybiusSquare; -public class ADFGX{ - private boolean preserveCapitals; - private boolean preserveWhitespace; - private boolean preserveSymbols; - private String inputString; - private String outputString; - private String squareKeyword; - private String keyword; - private PolybiusSquare polybiusSquare; - private Columnar columnar; +public class ADFGX{ + private String inputString; //This is the string that needs encoded/decoded + private String outputString; //This is the string that is output after encoding/decoding + private String squareKeyword; //The keyword used to create the Polybius Square + private String keyword; //The keyword used to create the Columnar cipher + private boolean preserveCapitals; //Whether to respect capitals in the output string + private boolean preserveWhitespace; //Whether to respect whitespace in the output string + private boolean preserveSymbols; //Whether to respect symbols in the output string + private PolybiusSquare polybiusSquare; //The first step in encoding + private Columnar columnar; //The second step in encoding + + //Ensures Polybius keyword constraints private void setSquareKeyword(String squareKeyword) throws InvalidKeywordException{ if(squareKeyword == null){ throw new InvalidKeywordException("Square Keyword cannot be null"); @@ -28,6 +31,7 @@ public class ADFGX{ this.squareKeyword = squareKeyword; } + //Ensures Columnar keyword constraints private void setKeyword(String keyword) throws InvalidKeywordException{ if(keyword == null){ throw new InvalidKeywordException("Keyword cannot be null"); @@ -35,6 +39,7 @@ public class ADFGX{ this.keyword = keyword; } + //Ensures inputString constraints private void setInputString(String inputString) throws InvalidInputException{ if(inputString == null){ throw new InvalidInputException("Input cannot be null"); @@ -56,6 +61,7 @@ public class ADFGX{ throw new InvalidInputException("Input cannot be blank"); } } + //Format the output string with capitals, symbols, and numbers that are in the input string private void formatOutputStringEncode(){ StringBuilder output = new StringBuilder(); int outputLocation = 0; @@ -94,37 +100,41 @@ public class ADFGX{ } outputString = output.toString(); } - private String encode() throws InvalidCharacterException, InvalidInputException, InvalidKeywordException{ + //Encodes the inputString and stores the result in outputString + private void encode() throws InvalidCharacterException, InvalidInputException, InvalidKeywordException{ //Encode the input with polybius String polybiusOutput = polybiusSquare.encode(squareKeyword, inputString); + squareKeyword = polybiusSquare.getKeyword(); //Change polybius to use the correct symbols polybiusOutput = polybiusOutput.replaceAll("1", "A").replaceAll("2", "D").replaceAll("3", "F").replaceAll("4", "G").replaceAll("5", "X"); //Encode polybius's output with columnar String columnarOutput = columnar.encode(keyword, polybiusOutput); + keyword = columnar.getKeyword(); outputString = columnarOutput; //Add whatever is needed to the output string formatOutputStringEncode(); - - return outputString; } - private String decode() throws InvalidKeywordException, InvalidCharacterException, InvalidInputException{ + //Decodes the inputString and stores the result in outputString + private void decode() throws InvalidKeywordException, InvalidCharacterException, InvalidInputException{ //Decode the input with columnar String columnarOutput = columnar.decode(keyword, inputString); + keyword = columnar.getKeyword(); //Change the symbols to the correct ones for polybius columnarOutput = columnarOutput.replaceAll("A", "1").replaceAll("D", "2").replaceAll("F", "3").replaceAll("G", "4").replaceAll("X", "5"); //Decode with polybius String polybiusOutput = polybiusSquare.decode(squareKeyword, columnarOutput); + squareKeyword = polybiusSquare.getKeyword(); outputString = polybiusOutput; //Add whatever is needed to the output string formatOutputStringDecode(); - - return outputString; } + + //Constructor public ADFGX() throws InvalidCharacterException{ preserveCapitals = false; preserveWhitespace = false; @@ -138,30 +148,40 @@ public class ADFGX{ reset(); } + //Encodes inputString using keyword and returns the result public String encode(String squareKeyword, String keyword, String inputString) throws InvalidKeywordException, InvalidInputException, InvalidCharacterException{ setSquareKeyword(squareKeyword); setKeyword(keyword); setInputString(inputString); - return encode(); + encode(); + return outputString; } + //Decodes inputString using keyword and returns the result public String decode(String squareKeyword, String keyword, String inputString) throws InvalidKeywordException, InvalidInputException, InvalidCharacterException{ setSquareKeyword(squareKeyword); setKeyword(keyword); setInputString(inputString); - return decode(); + decode(); + return outputString; } + + //Returns the cleaned inputString public String getInputString(){ return inputString; } + //Returns the outputString public String getOutputString(){ return outputString; } + //Returns the cleaned Polybius Square keyword public String getSquareKeyword(){ return squareKeyword; } + //Returns the cleaned Columnar keyword public String getKeyword(){ return keyword; } + //Makes sure all of the variables are empty public void reset() throws InvalidCharacterException{ polybiusSquare = new PolybiusSquare(false, false); columnar = new Columnar(false, false, false, true, 'B'); From 83595e5354a423eea006ceea01e07ac714057722 Mon Sep 17 00:00:00 2001 From: Matthew Ellison Date: Mon, 28 Feb 2022 19:22:45 +0000 Subject: [PATCH 3/3] Created Porta cipher --- .../monoSubstitution/Porta.java | 207 ++++++++++++++++++ 1 file changed, 207 insertions(+) create mode 100644 src/main/java/com/mattrixwv/CipherStreamJava/monoSubstitution/Porta.java diff --git a/src/main/java/com/mattrixwv/CipherStreamJava/monoSubstitution/Porta.java b/src/main/java/com/mattrixwv/CipherStreamJava/monoSubstitution/Porta.java new file mode 100644 index 0000000..958ce0c --- /dev/null +++ b/src/main/java/com/mattrixwv/CipherStreamJava/monoSubstitution/Porta.java @@ -0,0 +1,207 @@ +//CipherStreamJava/src/main/java/com/mattrixwv/CipherStreamJava/monoSubstitution/Porta.java +//Mattrixwv +// Created: 02-28-22 +//Modified: 02-28-22 +package com.mattrixwv.CipherStreamJava.monoSubstitution; + + +import com.mattrixwv.CipherStreamJava.exceptions.InvalidInputException; +import com.mattrixwv.CipherStreamJava.exceptions.InvalidKeywordException; + + +public class Porta{ + private static final String[] tableau = { + "NOPQRSTUVWXYZABCDEFGHIJKLM", //A-B + "OPQRSTUVWXYZNMABCDEFGHIJKL", //C-D + "PQRSTUVWXYZNOLMABCDEFGHIJK", //E-F + "QRSTUVWXYZNOPKLMABCDEFGHIJ", //G-H + "RSTUVWXYZNOPQJKLMABCDEFGHI", //I-J + "STUVWXYZNOPQRIJKLMABCDEFGH", //K-L + "TUVWXYZNOPQRSHIJKLMABCDEFG", //M-N + "UVWXYZNOPQRSTGHIJKLMABCDEF", //O-P + "VWXYZNOPQRSTUFGHIJKLMABCDE", //Q-R + "WXYZNOPQRSTUVEFGHIJKLMABCD", //S-T + "XYZNOPQRSTUVWDEFGHIJKLMABC", //U-V + "YZNOPQRSTUVWXCDEFGHIJKLMAB", //W-X + "ZNOPQRSTUVWXYBCDEFGHIJKLMA" //Y-Z + }; + + private String inputString; + private String outputString; + private String keyword; + private boolean preserveCapitals; + private boolean preserveWhitespace; + private boolean preserveSymbols; + + private void setKeyword(String keyword) throws InvalidKeywordException{ + //Make sure the keyword isn't null + if(keyword == null){ + throw new InvalidKeywordException("Keyword cannot be null"); + } + + //Convert all letters to uppercase + keyword = keyword.toUpperCase(); + //Remove all characters except capital letters and save the string + keyword = keyword.replaceAll("[^A-Z]", ""); + this.keyword = keyword; + + //If after eliminating all ususable characters the keyword is empty throw an exception + if(this.keyword.isBlank() || (this.keyword.length() < 2)){ + throw new InvalidKeywordException("Keyword must contain at least 2 letters"); + } + } + private void setInputString(String inputString) throws InvalidInputException{ + //Ensure the input isn't null + if(inputString == null){ + throw new InvalidInputException("Input cannot be null"); + } + + //Apply removal options + if(!preserveCapitals){ + inputString = inputString.toUpperCase(); + } + if(!preserveWhitespace){ + inputString = inputString.replaceAll("\\s", ""); + } + if(!preserveSymbols){ + inputString = inputString.replaceAll("[^a-zA-Z\\s]", ""); + } + + //Save the string + this.inputString = inputString; + + //Ensure the string isn't blank + if(this.inputString.isBlank()){ + throw new InvalidInputException("Input must contain at least 1 letter"); + } + } + private char getReplacer(int keywordCnt, char letter){ + char keyLetter = keyword.charAt(keywordCnt % keyword.length()); + int tableauColumn = (Character.toUpperCase(letter) - 'A'); + char replacer = '\0'; + + switch(keyLetter){ + case 'A': + case 'B': + replacer = tableau[0].charAt(tableauColumn); break; + case 'C': + case 'D': + replacer = tableau[1].charAt(tableauColumn); break; + case 'E': + case 'F': + replacer = tableau[2].charAt(tableauColumn); break; + case 'G': + case 'H': + replacer = tableau[3].charAt(tableauColumn); break; + case 'I': + case 'J': + replacer = tableau[4].charAt(tableauColumn); break; + case 'K': + case 'L': + replacer = tableau[5].charAt(tableauColumn); break; + case 'M': + case 'N': + replacer = tableau[6].charAt(tableauColumn); break; + case 'O': + case 'P': + replacer = tableau[7].charAt(tableauColumn); break; + case 'Q': + case 'R': + replacer = tableau[8].charAt(tableauColumn); break; + case 'S': + case 'T': + replacer = tableau[9].charAt(tableauColumn); break; + case 'U': + case 'V': + replacer = tableau[10].charAt(tableauColumn); break; + case 'W': + case 'X': + replacer = tableau[11].charAt(tableauColumn); break; + case 'Y': + case 'Z': + replacer = tableau[12].charAt(tableauColumn); break; + default: + replacer = letter; + } + + return replacer; + } + private void encode(){ + StringBuilder output = new StringBuilder(); + + //Step through every character in the inputString and advance it the correct amount according to the keyword and tableau + int keywordCnt = 0; + for(char letter : inputString.toCharArray()){ + //If the character is a letter replace with the corresponding character from the tableau + if(Character.isUpperCase(letter)){ + letter = Character.toUpperCase(getReplacer(keywordCnt, letter)); + ++keywordCnt; + } + else if(Character.isLowerCase(letter)){ + letter = Character.toLowerCase(getReplacer(keywordCnt, letter)); + ++keywordCnt; + } + + //Add the current character to the output + output.append(letter); + } + + //Save the output + outputString = output.toString(); + } + private void decode(){ + //Decoding is the same as encoding + encode(); + } + + + //Constructor + public Porta(){ + preserveCapitals = false; + preserveWhitespace = false; + preserveSymbols = false; + reset(); + } + public Porta(boolean preserveCapitals, boolean preserveWhitespace, boolean preserveSymbols){ + this.preserveCapitals = preserveCapitals; + this.preserveWhitespace = preserveWhitespace; + this.preserveSymbols = preserveSymbols; + reset(); + } + + public String encode(String keyword, String inputString) throws InvalidKeywordException, InvalidInputException{ + //Set the parameters + reset(); + setKeyword(keyword); + setInputString(inputString); + + //Encode and return the message + encode(); + return outputString; + } + public String decode(String keyword, String inputString) throws InvalidKeywordException, InvalidInputException{ + //Set the parameters + reset(); + setKeyword(keyword); + setInputString(inputString); + + //Decode and return the message + decode(); + return outputString; + } + + public String getInputString(){ + return inputString; + } + public String getOutputString(){ + return outputString; + } + public String getKeyword(){ + return keyword; + } + public void reset(){ + inputString = ""; + outputString = ""; + keyword = ""; + } +}