From 9b4da1f226c4cfe2d696f41f9b08040a2c5ac7bc Mon Sep 17 00:00:00 2001 From: Mattrixwv Date: Tue, 18 Jan 2022 23:14:33 -0500 Subject: [PATCH] Columnar started --- .../polySubstitution/Columnar.java | 162 ++++++++++++++++++ .../polySubstitution/TestColumnar.java | 20 +++ 2 files changed, 182 insertions(+) create mode 100644 src/main/java/com/mattrixwv/CipherStreamJava/polySubstitution/Columnar.java create mode 100644 src/test/java/com/mattrixwv/CipherStreamJava/polySubstitution/TestColumnar.java diff --git a/src/main/java/com/mattrixwv/CipherStreamJava/polySubstitution/Columnar.java b/src/main/java/com/mattrixwv/CipherStreamJava/polySubstitution/Columnar.java new file mode 100644 index 0000000..8cf1934 --- /dev/null +++ b/src/main/java/com/mattrixwv/CipherStreamJava/polySubstitution/Columnar.java @@ -0,0 +1,162 @@ +//MattrixwvWebsite/src/main/java/com/mattrixwv/CipherStreamJava/polySubstitution/Columnar.java +//Mattrixwv +// Created: 01-16-22 +//Modified: 01-16-22 +package com.mattrixwv.CipherStreamJava.polySubstitution; + +import java.util.ArrayList; +import java.util.Arrays; + +public class Columnar{ + 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 String inputString; //The message that needs to be encoded/decoded + private String outputString; //The encoded/decoded message + private String keyword; //The keyword used to create the grid + //TODO: Make this more robust + private char characterToAdd; //The character that is added to the end of a string to bring it to the correct length + private ArrayList> grid; //The grid used to encode/decode the message + + //Create the grid from the keyword + private void createGrid(){ + //Add the keyword to the first row in the array + grid.add(new ArrayList(Arrays.asList(keyword.chars().mapToObj(c -> (char)c).toArray(Character[]::new)))); + + //Create the input that will be used for encoding + StringBuilder gridInputString = new StringBuilder(); + gridInputString.append(inputString.toUpperCase().replaceAll("[^A-Za-z]", "")); + + //Make sure the input is the correct length + while((gridInputString.length() % keyword.length()) != 0){ + gridInputString.append(characterToAdd); + } + + //Create arrays from the inputString of keyword.size length and add them each as new rows to the grid + //?gridRow could be changed to grid.size(), but would it be worth the extra confusion? Probably not unless I really want to min/max + for(int gridRow = 1;(keyword.length() * gridRow) <= gridInputString.length();++gridRow){ + grid.add(new ArrayList(Arrays.asList( + gridInputString.substring(keyword.length() * (gridRow - 1), (keyword.length() * gridRow) + 1) + .chars().mapToObj(c->(char)c).toArray(Character[]::new) + ))); + } + } + //Strips invalid characters from the string that needs encoded/decoded + private void setInputString(String inputString){ + if(!preserveCapitals){ + inputString = inputString.toLowerCase(); + } + if(!preserveWhitespace){ + inputString = inputString.replaceAll("[\\s+]", ""); + } + if(!preserveSymbols){ + //TODO: Should numbers be treated like symbols? Probably, so this might need modified as well as testing; For all ciphers + inputString = inputString.replaceAll("[^a-zA-Z0-9\\s]", ""); + } + //TODO: Make sure that the input is not blank. This should be added to all ciphers + + this.inputString = inputString; + } + //Creates the output string from the grid + private String createOutputString(){ + //Check every character of the inputString and add the appropriate character to the output + int row = 1; + int col = 0; + StringBuilder output = new StringBuilder(); + for(char ch : inputString.toCharArray()){ + //If the character is a letter get the next letter from the grid + if(Character.isUpperCase(ch)){ + output.append(grid.get(row++).get(col)); + } + else if(Character.isLowerCase(ch)){ + output.append(grid.get(row++).get(col)); + } + //If the character is a symbol or whitespace add it to the output + else{ + output.append(ch); + } + + //Wrap around the grid when you reach the bottom + if(row == grid.size()){ + row = 1; + ++col; + } + } + + //Save and return the output + outputString = output.toString(); + return outputString; + } + //Strips invalid characters from the keyword and creates the grid + private void setKeyword(String keyword){ + this.keyword = keyword.toUpperCase().replaceAll("[^A-Z]", ""); + } + //Rearanges the grid based on the list of numbers given + private void rearangeList(ArrayList listOrder){ + //TODO: + } + //Encodes inputString using the Columnar cipher and stores the result in outputString + private String encode(){ + //TODO: + return null; + } + //Decodes inputString using the Columnar cipher and stores the result in outputString + private String decode(){ + //TODO: + return null; + } + + public Columnar(){ + preserveCapitals = false; + preserveWhitespace = false; + preserveSymbols = false; + characterToAdd = 'X'; + reset(); + } + public Columnar(boolean preserveCapitals, boolean preserveWhitespace, boolean preserveSymbols){ + this.preserveCapitals = preserveCapitals; + this.preserveWhitespace = preserveWhitespace; + this.preserveSymbols = preserveSymbols; + characterToAdd = 'X'; + reset(); + } + public Columnar(boolean preserveCapitals, boolean preserveWhitespace, boolean preserveSymbols, char characterToAdd){ + this.preserveCapitals = preserveCapitals; + this.preserveWhitespace = preserveWhitespace; + this.preserveSymbols = preserveSymbols; + characterToAdd = 'X'; + reset(); + } + //Sets the keyword, grid, and inputString and encodes the message + public String encode(String keyword, String inputString){ + setKeyword(keyword); + setInputString(inputString); + createGrid(); + return encode(); + } + //Sets the keyword, grid, and inputString and decodes the message + public String decode(String keyword, String inputString){ + setKeyword(keyword); + setInputString(inputString); + createGrid(); + return decode(); + } + + //Makes sure all variables are empty + public void reset(){ + inputString = ""; + outputString = ""; + keyword = ""; + grid = new ArrayList>(); + } + //Gets + public String getInputString(){ + return inputString; + } + public String getOutputString(){ + return outputString; + } + public String getKeyword(){ + return keyword; + } +} diff --git a/src/test/java/com/mattrixwv/CipherStreamJava/polySubstitution/TestColumnar.java b/src/test/java/com/mattrixwv/CipherStreamJava/polySubstitution/TestColumnar.java new file mode 100644 index 0000000..3104eb9 --- /dev/null +++ b/src/test/java/com/mattrixwv/CipherStreamJava/polySubstitution/TestColumnar.java @@ -0,0 +1,20 @@ +//Mattrixwv/src/test/java/com/mattrixwv/CipherStreamJava/polySubstitution/TestColumnar.java +//Mattrixwv +// Created: 01-16-22 +//Modified: 01-16-22 +package com.mattrixwv.CipherStreamJava.polySubstitution; + + +import org.junit.Test; + + +public class TestColumnar{ + @Test + public void testEncode(){ + Columnar cipher = new Columnar(true, true, true); + } + @Test + public void testDecode(){ + Columnar cipher = new Columnar(true, true, true); + } +}