diff --git a/pom.xml b/pom.xml
index 65d1499..1f9805b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -13,8 +13,9 @@
UTF-8
- 14
- 14
+ 17
+ 17
+ 17
diff --git a/src/main/java/mattrixwv/CipherStreamJava/Playfair.java b/src/main/java/mattrixwv/CipherStreamJava/Playfair.java
index 00cdd2f..09d00da 100644
--- a/src/main/java/mattrixwv/CipherStreamJava/Playfair.java
+++ b/src/main/java/mattrixwv/CipherStreamJava/Playfair.java
@@ -7,32 +7,23 @@ package mattrixwv.CipherStreamJava;
public class Playfair{
- //Classes to help with error handling
- private class LetterNotFound{
- private char letter;
- public LetterNotFound(char letter){
- this.letter = letter;
+ //An exception to indicate a bad string was given as a parameter
+ public class InvalidCharacterException extends Exception{
+ InvalidCharacterException(){
+ super();
}
- public char getLetter(){
- return letter;
+ InvalidCharacterException(String message){
+ super(message);
}
- }
- public class InvalidGrid{
- private String type;
- private int size;
- public InvalidGrid(String type, int size){
- this.type = type;
- this.size = size;
- }
- public String getType(){
- return type;
- }
- public int getSize(){
- return size;
+ InvalidCharacterException(String message, Throwable throwable){
+ super(message, throwable);
}
}
//Variables
+ private boolean leaveCapitals; //Whether to respect captials in the output string
+ private boolean leaveWhitespace; //Whether to respect whitespace in the output string
+ private boolean leaveSymbols; //Whether to respect symbols in the output string
private char replaced; //The letter that will need to be replaced in the grid and any input string or keyword
private char replacer; //The letter that replaced replaced in the input string or keyword
private char doubled; //The letter that will be placed between double letters in the input string if necessary or to make the string length even
@@ -42,57 +33,127 @@ public class Playfair{
private char[][] grid; //The grid used to encoded/decode the message
//Create the grid from the keyword
private void createGrid(){
- int row = 0;
- int column = 0;
- boolean found = false;
-
- //Add any new letters from the keyword to the grid
- //If you reach row 5 then the entire grid has been filled
- char current = '\0';
- for(int cnt = 0;(cnt < keyword.length()) && (row < 5);++cnt){
- current = keyword.charAt(cnt);
- //If the current letter needs to be replaced, do so
- if(current == replaced){
- current = replacer;
- }
-
- //Search the grid for the current letter
- found = checkGrid(current);
-
- //If the letter is not in the grid add it
- if(!found){
- grid[row][column] = keyword.charAt(cnt);
- ++column;
- //If the column number is too high reset it and advance the row
- if(column >= 5){
- column = 0;
- ++row;
- }
+ for(int row = 0;row < 5;++row){
+ for(int col = 0;col < 5;++col){
+ char letter = keyword.charAt((5 * row) + col);
+ grid[row][col] = letter;
}
}
}
- //Returns true if the letter is found in the grid
- private boolean checkGrid(char letter){
- //TODO:
- return true;
- }
- //Searches the grid for letter and sets row & col to its location in grid
- //TODO: This needs to be reworked
- private void searchGrid(char letter, int row, int col){
- //TODO:
- }
//Strips invalid characters from the string that needs encoded/decoded
- private void setInputString(String input){
- //TODO:
+ private void setInputString(String inputString) throws InvalidCharacterException{
+ //Make sure the input string is not null
+ if(inputString == null){
+ throw new InvalidCharacterException("The input string cannot be null");
+ }
+
+ //Set the options
+ if(!leaveCapitals){
+ inputString.toLowerCase();
+ }
+ if(!leaveWhitespace){
+ inputString = inputString.replaceAll("\\s+", "");
+ }
+ if(!leaveSymbols){
+ inputString = inputString.replaceAll("[^a-zA-Z0-9\\s+]", "");
+ }
+
+ //Make replace all of the replacers with replaced
+ inputString = inputString.replaceAll(Character.toString(replaced), Character.toString(replacer));
+
+ //If there is nothing in the input string throw an exception
+ if(inputString.isBlank()){
+ throw new InvalidCharacterException("The input string cannot be blank");
+ }
+
+ //Replace characters that need replaced
+ StringBuilder sanitizedInput = new StringBuilder();
+ for(int inputCnt = 0;inputCnt < inputString.length();++inputCnt){
+ //Get the first letter
+ char firstLetter = inputString.charAt(inputCnt++);
+ //Make sure the first letter doesn't need replaced
+ if(firstLetter == replaced){
+ firstLetter = replacer;
+ }
+
+ //Save all of the characters inbetween letters
+ StringBuilder inBetween = new StringBuilder();
+ while((!Character.isAlphabetic(inputString.charAt(inputCnt))) && (inputCnt != inputString.length())){
+ inBetween.append(inputString.charAt(inputCnt++));
+ }
+
+ //Get the second letter
+ char secondLetter = '\0';
+ if(inputCnt != inputString.length()){
+ secondLetter = inputString.charAt(inputCnt++);
+ }
+ else{
+ secondLetter = doubled;
+ }
+ //Make sure the second letter doesn't need replaced
+ if(secondLetter == replaced){
+ secondLetter = replacer;
+ }
+ if(secondLetter == firstLetter){
+ secondLetter = doubled;
+ --inputCnt;
+ }
+
+ //Add the letters to the sanitized string
+ sanitizedInput.append(firstLetter);
+ sanitizedInput.append(inBetween.toString());
+ sanitizedInput.append(secondLetter);
+ }
+ this.inputString = sanitizedInput.toString();
+ }
+ //Returns the inputs string ready for encoding
+ private String getPreparedInputString(){
+ String cleanString = inputString.toUpperCase();
+ cleanString = cleanString.replaceAll("[^A-Z]", "");
+ return cleanString;
}
//Strips invalid character from the keyword and creates the grid
private void setKeyword(String key){
- //TODO:
+ //Change everything to uppercase
+ key = key.toUpperCase();
+
+ //Removing everything except capital letters
+ key = key.replaceAll("[^A-Z]", "");
+
+ //Add all letters in the alphabet to the key
+ key += "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+ //Replace all replaced characters
+ key = key.replaceAll(Character.toString(replaced), Character.toString(replacer));
+
+ //Remove all duplicate chatacters
+ StringBuilder uniqueKey = new StringBuilder();
+ key.chars().distinct().forEach(c -> uniqueKey.append((char)c));
+ keyword = uniqueKey.toString();
+
+ //Create the grid from the sanitized keyword
+ createGrid();
}
//Encoded inputString using the Playfair cipher and stores the result in outputString
private String encode(){
- //TODO:
- return null;
+ StringBuilder output = new StringBuilder();
+ int inputCnt = 0;
+ String cleanString = getPreparedInputString();
+ while(inputCnt < inputString.length()){
+ //Get the next 2 letters to be encoded
+ char firstLetter = inputString.charAt(inputCnt++);
+ char secondLetter = '\0';
+ StringBuilder inBetween = new StringBuilder();
+
+ //TODO:
+ //Find the letters in the grid
+
+ //Encode the letters
+
+ //Add the new letters to the output string
+ }
+
+ //Return the output string
}
//Decodes inputString using the Playfair cipher and stores the result in outputString
private String decode(){
@@ -105,40 +166,110 @@ public class Playfair{
replaced = 'J';
replacer = 'I';
doubled = 'X';
+ leaveCapitals = false;
+ leaveWhitespace = false;
+ leaveSymbols = false;
+ }
+ public Playfair(boolean leaveCapitals, boolean leaveWhitespace, boolean leaveSymbols){
+ reset();
+ replaced = 'J';
+ replacer = 'I';
+ doubled = 'X';
+ this.leaveCapitals = leaveCapitals;
+ this.leaveWhitespace = leaveWhitespace;
+ this.leaveSymbols = leaveSymbols;
+ }
+ public Playfair(boolean leaveCapitals, boolean leaveWhitespace, boolean leaveSymbols, char replaced, char replacer, char doubled) throws InvalidCharacterException{
+ reset();
+ setReplaced(replaced);
+ setReplacer(replacer);
+ setDoubled(doubled);
+ this.leaveCapitals = leaveCapitals;
+ this.leaveWhitespace = leaveWhitespace;
+ this.leaveSymbols = leaveSymbols;
}
//Sets the keyword and inputString and encodes the message
- public String encode(String keyword, String input){
- //TODO:
- return null;
+ public String encode(String keyword, String input) throws InvalidCharacterException{
+ reset();
+ setKeyword(keyword);
+ setInputString(input);
+ return encode();
}
//Sets the keyword and inputString and decodes the message
- public String decode(String keyword, String input){
- //TODO:
- return null;
+ public String decode(String keyword, String input) throws InvalidCharacterException{
+ reset();
+ setKeyword(keyword);
+ setInputString(input);
+ return decode();
}
//Makes sure all variables are empty
public void reset(){
- //TODO:
+ grid = new char[5][5];
}
//Gets
public char getReplaced(){
return replaced;
}
- public void setReplaced(char replaced){
- //TODO:
+ public void setReplaced(char replaced) throws InvalidCharacterException{
+ if(!Character.isAlphabetic(replaced)){
+ throw new InvalidCharacterException("The replaced characgter must be a letter");
+ }
+
+ if(replaced == replacer){
+ throw new InvalidCharacterException("The replaced letter cannot be the same as the replacing letter");
+ }
+
+ if(replaced == doubled){
+ throw new InvalidCharacterException("The replaced letter cannot be the same as the replacing letter");
+ }
+
+ if((Character.isAlphabetic(replaced)) && (replaced != replacer)){
+ this.replaced = Character.toUpperCase(replaced);
+ }
}
public char getReplacer(){
return replacer;
}
- public void setReplacer(char replacer){
- //TODO:
+ public void setReplacer(char replacer) throws InvalidCharacterException{
+ //Make sure the character is a letter
+ if(!Character.isAlphabetic(replacer)){
+ throw new InvalidCharacterException("The replacer must be a letter");
+
+ }
+
+ //Make sure the character isn't the same as what it is supposed to replace
+ if(replacer == replaced){
+ throw new InvalidCharacterException("The replacer cannot be the same letter as what it is replacing");
+ }
+
+ //Make sure the replacer isn't the same as the double letter replacer
+ if(replacer == doubled){
+ throw new InvalidCharacterException("The replacer cannot be the same as the double letter replacer");
+ }
+
+ this.replacer = Character.toUpperCase(replacer);
}
public char getDoubled(){
return doubled;
}
- public void setDoubled(char doubled){
- //TODO:
+ public void setDoubled(char doubled) throws InvalidCharacterException{
+ //Make sure the character is a letter
+ if(!Character.isAlphabetic(doubled)){
+ throw new InvalidCharacterException("The double letter replacement must be a letter");
+ }
+
+ //Make sure the 2 replacers are the same
+ if(doubled == replacer){
+ throw new InvalidCharacterException("The double letter replacement cannot be the same as the regular replacer");
+ }
+
+ //Make sure the double letter replacement isn't the same as the letter being replaced
+ if(doubled == replaced){
+ throw new InvalidCharacterException("The double letter replacement cannot be the same as the letter replaced");
+ }
+
+ this.doubled = Character.toUpperCase(doubled);
}
public String getKeyword(){
return keyword;
@@ -150,7 +281,13 @@ public class Playfair{
return outputString;
}
public String getGrid(){
- //TODO:
- return null;
+ StringBuilder gridString = new StringBuilder();
+ for(char[] row : grid){
+ for(char col : row){
+ gridString.append(col);
+ }
+ }
+
+ return gridString.toString();
}
}