diff --git a/src/main/java/mattrixwv/CipherStreamJava/Autokey.java b/src/main/java/mattrixwv/CipherStreamJava/Autokey.java new file mode 100644 index 0000000..7bf7c6e --- /dev/null +++ b/src/main/java/mattrixwv/CipherStreamJava/Autokey.java @@ -0,0 +1,106 @@ +//CipherStreamJava/src/main/java/mattrixwv/CipherStreamJava/Autokey.java +//Matthew Ellison +// Created: 07-25-21 +//Modified: 12-30--21 +//This is the declaration of the Autokey class +package mattrixwv.CipherStreamJava; + + +public class Autokey extends Vigenere{ + //Special rules for setting the strings for encoding + private void encodeSet(String key, String input) throws Exception{ + //Set the input + setInputString(input); + + StringBuilder newKey = new StringBuilder(); + //Remove all unneccessary elements from the key + setKeyword(key); + newKey.append(keyword); + //Remove all unneccessary elements from the input + setKeyword(input); + newKey.append(getKeyword()); + + //Make sure the key is not any longer than the input + key = newKey.substring(0, getKeyword().length()); + + //Set the new keyword + setKeyword(key); + //Make sure to update the offset + offset.clear(); + setOffset(); + } + //Setting the strings for decoding + private void decodeSet(String key, String input) throws Exception{ + //Remove all unneccessary elements from the key + setKeyword(key); + //Remove all unneccessary elements from the input + inputString = ""; + setInputString(input); + } + //Decodes the inputString + protected String decode() throws Exception{ + //Decode what the key will allow, add that to the key and continue + StringBuilder currentOutput = new StringBuilder(); + StringBuilder fullOutput = new StringBuilder(); + + //Step through every character in the inputString and advance it the correct amount, according to offset + int offsetCnt = 0; + for(int letterCnt = 0;letterCnt < inputString.length();++letterCnt){ + //If we have reached the end of the keyword add what we have to it and continue + if(offsetCnt == keyword.length()){ + setKeyword(keyword + currentOutput.toString()); + fullOutput.append(currentOutput); + currentOutput = new StringBuilder(); + } + + char letter = inputString.charAt(letterCnt); + if(Character.isUpperCase(letter)){ + letter -= offset.get((offsetCnt++) % offset.size()); + if(letter < 'A'){ + letter += 26; + } + else if(letter > 'Z'){ + letter -= 26; + } + } + else if(Character.isLowerCase(letter)){ + letter -= offset.get((offsetCnt++) % offset.size()); + if(letter < 'a'){ + letter += 26; + } + else if(letter > 'z'){ + letter -= 26; + } + } + currentOutput.append(letter); + } + //Empty the last character that were decoded + fullOutput.append(currentOutput); + + //Save and return the results + outputString = fullOutput.toString(); + return outputString; + } + + + //Constructor + public Autokey(){ + super(); + } + public Autokey(boolean leaveCapitals, boolean leaveWhitespace, boolean leaveSymbols){ + super(leaveCapitals, leaveWhitespace, leaveSymbols); + } + //Encodes inputString using the Autokey cipher + public String encode(String key, String input) throws Exception{ + reset(); + encodeSet(key, input); + return encode(); + } + //Decodes inputString using the Autokey cipher + public String decode(String key, String input) throws Exception{ + reset(); + setInputString(input); + decodeSet(key, input); + return decode(); + } +} diff --git a/src/main/java/mattrixwv/CipherStreamJava/Vigenere.java b/src/main/java/mattrixwv/CipherStreamJava/Vigenere.java index 1b67102..10a55cf 100644 --- a/src/main/java/mattrixwv/CipherStreamJava/Vigenere.java +++ b/src/main/java/mattrixwv/CipherStreamJava/Vigenere.java @@ -92,7 +92,7 @@ public class Vigenere{ return outputString; } //Decodes inputString and stores the result in outputString - protected String decode(){ + protected String decode() throws Exception{ StringBuilder output = new StringBuilder(); //Step through every character in the inputString and advance it the correct amount, according to offset diff --git a/src/test/java/mattrixwv/CipherStreamJava/TestAutokey.java b/src/test/java/mattrixwv/CipherStreamJava/TestAutokey.java new file mode 100644 index 0000000..52dbeb2 --- /dev/null +++ b/src/test/java/mattrixwv/CipherStreamJava/TestAutokey.java @@ -0,0 +1,523 @@ +//CipherStreamJava/src/main/java/mattrixwv/CipherStreamJava/TestAutokey.java +//Matthew Ellison +// Created: 07-26-21 +//Modified: 12-30-21 +//These are the tests for the Vigenere class +package mattrixwv.CipherStreamJava; + + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + + +public class TestAutokey{ + @Test + public void testDecode() throws Exception{ + Autokey cipher = new Autokey(true, true, true); + + //Test lowercase decoding + String input = "qnxepv"; + String keyword = "queenly"; + String correctOutput = "attack"; + String output = cipher.decode(keyword, input); + assertEquals("Autokey failed lowercase decoding.", correctOutput, output); + //Test uppercase decoding + input = "QNXEPV"; + keyword = "queenly"; + correctOutput = "ATTACK"; + output = cipher.decode(keyword, input); + assertEquals("Autokey failed uppercase decoding.", correctOutput, output); + + + //Test whitespace decoding + input = "qnxepv yt wtwp"; + keyword = "queenly"; + correctOutput = "attack at dawn"; + output = cipher.decode(keyword, input); + assertEquals("Autokey failed whitespace decoding.", correctOutput, output); + + + //Test symbol decoding + input = "qnxepv@yt-wtwp"; + keyword = "queenly"; + correctOutput = "attack@at-dawn"; + output = cipher.decode(keyword, input); + assertEquals("Autokey failed symbol decoding.", correctOutput, output); + + + //Test mixed case, whitespace, symbol decoding + input = "Qnxepv yt - wtwp"; + keyword = "QUEENLY"; + correctOutput = "Attack at - dawn"; + output = cipher.decode(keyword, input); + assertEquals("Autokey failed mixed case, whitespace, symbol decoding.", correctOutput, output); + //Test mixed case, whitespace, symbol decoding with mangled keyword + input = "Wmpm mx \"Xae Yhbryoca\""; + keyword = "k@i l-t"; + correctOutput = "Meet at \"The Fountain\""; + output = cipher.decode(keyword, input); + assertEquals("Autokey failed mixed case, whitespace, symbol decoding with mangled keyword.", correctOutput, output); + } + @Test + public void testNoWhitespaceDecode() throws Exception{ + Autokey cipher = new Autokey(true, false, true); + + //Test lowercase decoding + String input = "qnxepv"; + String keyword = "queenly"; + String correctOutput = "attack"; + String output = cipher.decode(keyword, input); + assertEquals("Autokey failed no whitespace lowercase decoding.", correctOutput, output); + //Test uppercase decoding + input = "QNXEPV"; + keyword = "queenly"; + correctOutput = "ATTACK"; + output = cipher.decode(keyword, input); + assertEquals("Autokey failed no whitespace uppercase decoding.", correctOutput, output); + + + //Test whitespace decoding + input = "qnxepv yt wtwp"; + keyword = "queenly"; + correctOutput = "attackatdawn"; + output = cipher.decode(keyword, input); + assertEquals("Autokey failed no whitespace whitespace decoding.", correctOutput, output); + + + //Test symbol decoding + input = "qnxepv@yt-wtwp"; + keyword = "queenly"; + correctOutput = "attack@at-dawn"; + output = cipher.decode(keyword, input); + assertEquals("Autokey failed no whitespace symbol decoding.", correctOutput, output); + + + //Test mixed case, whitespace, symbol decoding + input = "Qnxepv yt - wtwp"; + keyword = "QUEENLY"; + correctOutput = "Attackat-dawn"; + output = cipher.decode(keyword, input); + assertEquals("Autokey failed no whitespace mixed case, whitespace, symbol decoding.", correctOutput, output); + //Test mixed case, whitespace, symbol decoding with mangled keyword + input = "Wmpm mx \"Xae Yhbryoca\""; + keyword = "k@i l-t"; + correctOutput = "Meetat\"TheFountain\""; + output = cipher.decode(keyword, input); + assertEquals("Autokey failed no whitespace mixed case, whitespace, symbol decoding with mangled keyword.", correctOutput, output); + } + @Test + public void testNoCapitalDecode() throws Exception{ + Autokey cipher = new Autokey(false, true, true); + + //Test lowercase decoding + String input = "qnxepv"; + String keyword = "queenly"; + String correctOutput = "attack"; + String output = cipher.decode(keyword, input); + assertEquals("Autokey failed no capital lowercase decoding.", correctOutput, output); + //Test uppercase decoding + input = "QNXEPV"; + keyword = "queenly"; + correctOutput = "attack"; + output = cipher.decode(keyword, input); + assertEquals("Autokey failed no capital uppercase decoding.", correctOutput, output); + + + //Test whitespace decoding + input = "qnxepv yt wtwp"; + keyword = "queenly"; + correctOutput = "attack at dawn"; + output = cipher.decode(keyword, input); + assertEquals("Autokey failed no capital whitespace decoding.", correctOutput, output); + + + //Test symbol decoding + input = "qnxepv@yt-wtwp"; + keyword = "queenly"; + correctOutput = "attack@at-dawn"; + output = cipher.decode(keyword, input); + assertEquals("Autokey failed no capital symbol decoding.", correctOutput, output); + + + //Test mixed case, whitespace, symbol decoding + input = "Qnxepv yt - wtwp"; + keyword = "QUEENLY"; + correctOutput = "attack at - dawn"; + output = cipher.decode(keyword, input); + assertEquals("Autokey failed no capital mixed case, whitespace, symbol decoding.", correctOutput, output); + //Test mixed case, whitespace, symbol decoding with mangled keyword + input = "Wmpm mx \"Xae Yhbryoca\""; + keyword = "k@i l-t"; + correctOutput = "meet at \"the fountain\""; + output = cipher.decode(keyword, input); + assertEquals("Autokey failed no capital mixed case, whitespace, symbol decoding with mangled keyword.", correctOutput, output); + } + @Test + public void testNoSymbolDecode() throws Exception{ + Autokey cipher = new Autokey(true, true, false); + + //Test lowercase decoding + String input = "qnxepv"; + String keyword = "queenly"; + String correctOutput = "attack"; + String output = cipher.decode(keyword, input); + assertEquals("Autokey failed no symbol lowercase decoding.", correctOutput, output); + //Test uppercase decoding + input = "QNXEPV"; + keyword = "queenly"; + correctOutput = "ATTACK"; + output = cipher.decode(keyword, input); + assertEquals("Autokey failed no symbol uppercase decoding.", correctOutput, output); + + + //Test whitespace decoding + input = "qnxepv yt wtwp"; + keyword = "queenly"; + correctOutput = "attack at dawn"; + output = cipher.decode(keyword, input); + assertEquals("Autokey failed no symbol whitespace decoding.", correctOutput, output); + + + //Test symbol decoding + input = "qnxepv@yt-wtwp"; + keyword = "queenly"; + correctOutput = "attackatdawn"; + output = cipher.decode(keyword, input); + assertEquals("Autokey failed no symbol symbol decoding.", correctOutput, output); + + + //Test mixed case, whitespace, symbol decoding + input = "Qnxepv yt - wtwp"; + keyword = "QUEENLY"; + correctOutput = "Attack at dawn"; + output = cipher.decode(keyword, input); + assertEquals("Autokey failed no symbol mixed case, whitespace, symbol decoding.", correctOutput, output); + //Test mixed case, whitespace, symbol decoding with mangled keyword + input = "Wmpm mx \"Xae Yhbryoca\""; + keyword = "k@i l-t"; + correctOutput = "Meet at The Fountain"; + output = cipher.decode(keyword, input); + assertEquals("Autokey failed no symbol mixed case, whitespace, symbol decoding with mangled keyword.", correctOutput, output); + } + @Test + public void testNoCapitalWhitespaceSymbolDecode() throws Exception{ + Autokey cipher = new Autokey(false, false, false); + + //Test lowercase decoding + String input = "qnxepv"; + String keyword = "queenly"; + String correctOutput = "attack"; + String output = cipher.decode(keyword, input); + assertEquals("Autokey failed secure lowercase decoding.", correctOutput, output); + //Test uppercase decoding + input = "QNXEPV"; + keyword = "queenly"; + correctOutput = "attack"; + output = cipher.decode(keyword, input); + assertEquals("Autokey failed secure uppercase decoding.", correctOutput, output); + + + //Test whitespace decoding + input = "qnxepv yt wtwp"; + keyword = "queenly"; + correctOutput = "attackatdawn"; + output = cipher.decode(keyword, input); + assertEquals("Autokey failed secure whitespace decoding.", correctOutput, output); + + + //Test symbol decoding + input = "qnxepv@yt-wtwp"; + keyword = "queenly"; + correctOutput = "attackatdawn"; + output = cipher.decode(keyword, input); + assertEquals("Autokey failed secure symbol decoding.", correctOutput, output); + + + //Test mixed case, whitespace, symbol decoding + input = "Qnxepv yt - wtwp"; + keyword = "QUEENLY"; + correctOutput = "attackatdawn"; + output = cipher.decode(keyword, input); + assertEquals("Autokey failed secure mixed case, whitespace, symbol decoding.", correctOutput, output); + //Test mixed case, whitespace, symbol decoding with mangled keyword + input = "Wmpm mx \"Xae Yhbryoca\""; + keyword = "k@i l-t"; + correctOutput = "meetatthefountain"; + output = cipher.decode(keyword, input); + assertEquals("Autokey failed secure mixed case, whitespace, symbol decoding with mangled keyword.", correctOutput, output); + } + + + @Test + public void testEncode() throws Exception{ + Autokey cipher = new Autokey(true, true, true); + + //Test lowercase decoding + String input = "attack"; + String keyword = "queenly"; + String correctOutput = "qnxepv"; + String output = cipher.encode(keyword, input); + assertEquals("Autokey failed lowercase decoding.", correctOutput, output); + //Test uppercase decoding + input = "ATTACK"; + keyword = "queenly"; + correctOutput = "QNXEPV"; + output = cipher.encode(keyword, input); + assertEquals("Autokey failed uppercase decoding.", correctOutput, output); + + + //Test whitespace decoding + input = "attack at dawn"; + keyword = "queenly"; + correctOutput = "qnxepv yt wtwp"; + output = cipher.encode(keyword, input); + assertEquals("Autokey failed whitespace decoding.", correctOutput, output); + + + //Test symbol decoding + input = "attack@at-dawn"; + keyword = "queenly"; + correctOutput = "qnxepv@yt-wtwp"; + output = cipher.encode(keyword, input); + assertEquals("Autokey failed symbol decoding.", correctOutput, output); + + + //Test mixed case, whitespace, symbol encoding + input = "Attack at - dawn"; + keyword = "QUEENLY"; + correctOutput = "Qnxepv yt - wtwp"; + output = cipher.encode(keyword, input); + assertEquals("Autokey failed mixed case, whitespace, symbol decoding.", correctOutput, output); + //Test mixed case, whitespace, symbol decoding with mangled keyword + input = "Meet at \"The Fountain\""; + keyword = "k@i l-t"; + correctOutput = "Wmpm mx \"Xae Yhbryoca\""; + output = cipher.encode(keyword, input); + assertEquals("Autokey failed mixed case, whitespace, symbol decoding with mangled keyword.", correctOutput, output); + } + @Test + public void testNoWhitespaceEncode() throws Exception{ + Autokey cipher = new Autokey(true, false, true); + + //Test lowercase decoding + String input = "attack"; + String keyword = "queenly"; + String correctOutput = "qnxepv"; + String output = cipher.encode(keyword, input); + assertEquals("Autokey failed no whitespace lowercase decoding.", correctOutput, output); + //Test uppercase decoding + input = "ATTACK"; + keyword = "queenly"; + correctOutput = "QNXEPV"; + output = cipher.encode(keyword, input); + assertEquals("Autokey failed no whitespace uppercase decoding.", correctOutput, output); + + + //Test whitespace decoding + input = "attack at dawn"; + keyword = "queenly"; + correctOutput = "qnxepvytwtwp"; + output = cipher.encode(keyword, input); + assertEquals("Autokey failed no whitespace whitespace decoding.", correctOutput, output); + + + //Test symbol decoding + input = "attack@at-dawn"; + keyword = "queenly"; + correctOutput = "qnxepv@yt-wtwp"; + output = cipher.encode(keyword, input); + assertEquals("Autokey failed no whitespace symbol decoding.", correctOutput, output); + + + //Test mixed case, whitespace, symbol encoding + input = "Attack at - dawn"; + keyword = "QUEENLY"; + correctOutput = "Qnxepvyt-wtwp"; + output = cipher.encode(keyword, input); + assertEquals("Autokey failed no whitespace mixed case, whitespace, symbol decoding.", correctOutput, output); + //Test mixed case, whitespace, symbol decoding with mangled keyword + input = "Meet at \"The Fountain\""; + keyword = "k@i l-t"; + correctOutput = "Wmpmmx\"XaeYhbryoca\""; + output = cipher.encode(keyword, input); + assertEquals("Autokey failed no whitespace mixed case, whitespace, symbol decoding with mangled keyword.", correctOutput, output); + } + @Test + public void testNoCapitalEncode() throws Exception{ + Autokey cipher = new Autokey(false, true, true); + + //Test lowercase decoding + String input = "attack"; + String keyword = "queenly"; + String correctOutput = "qnxepv"; + String output = cipher.encode(keyword, input); + assertEquals("Autokey failed no capital lowercase decoding.", correctOutput, output); + //Test uppercase decoding + input = "ATTACK"; + keyword = "queenly"; + correctOutput = "qnxepv"; + output = cipher.encode(keyword, input); + assertEquals("Autokey failed no capital uppercase decoding.", correctOutput, output); + + + //Test whitespace decoding + input = "attack at dawn"; + keyword = "queenly"; + correctOutput = "qnxepv yt wtwp"; + output = cipher.encode(keyword, input); + assertEquals("Autokey failed no capital whitespace decoding.", correctOutput, output); + + + //Test symbol decoding + input = "attack@at-dawn"; + keyword = "queenly"; + correctOutput = "qnxepv@yt-wtwp"; + output = cipher.encode(keyword, input); + assertEquals("Autokey failed no capital symbol decoding.", correctOutput, output); + + + //Test mixed case, whitespace, symbol encoding + input = "Attack at - dawn"; + keyword = "QUEENLY"; + correctOutput = "qnxepv yt - wtwp"; + output = cipher.encode(keyword, input); + assertEquals("Autokey failed no capital mixed case, whitespace, symbol decoding.", correctOutput, output); + //Test mixed case, whitespace, symbol decoding with mangled keyword + input = "Meet at \"The Fountain\""; + keyword = "k@i l-t"; + correctOutput = "wmpm mx \"xae yhbryoca\""; + output = cipher.encode(keyword, input); + assertEquals("Autokey failed no capital mixed case, whitespace, symbol decoding with mangled keyword.", correctOutput, output); + } + @Test + public void testNoSymbolEncode() throws Exception{ + Autokey cipher = new Autokey(true, true, false); + + //Test lowercase decoding + String input = "attack"; + String keyword = "queenly"; + String correctOutput = "qnxepv"; + String output = cipher.encode(keyword, input); + assertEquals("Autokey failed no symbol lowercase decoding.", correctOutput, output); + //Test uppercase decoding + input = "ATTACK"; + keyword = "queenly"; + correctOutput = "QNXEPV"; + output = cipher.encode(keyword, input); + assertEquals("Autokey failed no symbol uppercase decoding.", correctOutput, output); + + + //Test whitespace decoding + input = "attack at dawn"; + keyword = "queenly"; + correctOutput = "qnxepv yt wtwp"; + output = cipher.encode(keyword, input); + assertEquals("Autokey failed no symbol whitespace decoding.", correctOutput, output); + + + //Test symbol decoding + input = "attack@at-dawn"; + keyword = "queenly"; + correctOutput = "qnxepvytwtwp"; + output = cipher.encode(keyword, input); + assertEquals("Autokey failed no symbol symbol decoding.", correctOutput, output); + + + //Test mixed case, whitespace, symbol encoding + input = "Attack at - dawn"; + keyword = "QUEENLY"; + correctOutput = "Qnxepv yt wtwp"; + output = cipher.encode(keyword, input); + assertEquals("Autokey failed no symbol mixed case, whitespace, symbol decoding.", correctOutput, output); + //Test mixed case, whitespace, symbol decoding with mangled keyword + input = "Meet at \"The Fountain\""; + keyword = "k@i l-t"; + correctOutput = "Wmpm mx Xae Yhbryoca"; + output = cipher.encode(keyword, input); + assertEquals("Autokey failed no symbol mixed case, whitespace, symbol decoding with mangled keyword.", correctOutput, output); + } + @Test + public void testNoCapitalWhitespaceSymbolEncode() throws Exception{ + Autokey cipher = new Autokey(false, false, false); + + //Test lowercase decoding + String input = "attack"; + String keyword = "queenly"; + String correctOutput = "qnxepv"; + String output = cipher.encode(keyword, input); + assertEquals("Autokey failed secure lowercase decoding.", correctOutput, output); + //Test uppercase decoding + input = "ATTACK"; + keyword = "queenly"; + correctOutput = "qnxepv"; + output = cipher.encode(keyword, input); + assertEquals("Autokey failed secure uppercase decoding.", correctOutput, output); + + + //Test whitespace decoding + input = "attack at dawn"; + keyword = "queenly"; + correctOutput = "qnxepvytwtwp"; + output = cipher.encode(keyword, input); + assertEquals("Autokey failed secure whitespace decoding.", correctOutput, output); + + + //Test symbol decoding + input = "attack@at-dawn"; + keyword = "queenly"; + correctOutput = "qnxepvytwtwp"; + output = cipher.encode(keyword, input); + assertEquals("Autokey failed secure symbol decoding.", correctOutput, output); + + + //Test mixed case, whitespace, symbol encoding + input = "Attack at - dawn"; + keyword = "QUEENLY"; + correctOutput = "qnxepvytwtwp"; + output = cipher.encode(keyword, input); + assertEquals("Autokey failed secure mixed case, whitespace, symbol decoding.", correctOutput, output); + //Test mixed case, whitespace, symbol decoding with mangled keyword + input = "Meet at \"The Fountain\""; + keyword = "k@i l-t"; + correctOutput = "wmpmmxxaeyhbryoca"; + output = cipher.encode(keyword, input); + assertEquals("Autokey failed secure mixed case, whitespace, symbol decoding with mangled keyword.", correctOutput, output); + } + + + @Test + public void testKeyword() throws Exception{ + Autokey cipher = new Autokey(); + + //Test keyword with whitespace + String keyword = "x y z "; + String correctOutput = "XYZ"; + cipher.setKeyword(keyword); + String output = cipher.getKeyword(); + assertEquals("Vigenere failed keyword with whitespace", correctOutput, output); + + + //Test keyword with symbol + keyword = "x-y@z0"; + correctOutput = "XYZ"; + cipher.setKeyword(keyword); + output = cipher.getKeyword(); + assertEquals("Vigenere failed keyword with symbol", correctOutput, output); + + + //Test keyword with mixed case + keyword = "xYz"; + correctOutput = "XYZ"; + cipher.setKeyword(keyword); + output = cipher.getKeyword(); + assertEquals("Vigenere failed keyword with mixed case", correctOutput, output); + + //Test keyword with whitespace, symbol and keyword + keyword = "x Y%z "; + correctOutput = "XYZ"; + cipher.setKeyword(keyword); + output = cipher.getKeyword(); + assertEquals("Vigenere failed keyword with space, symbol, and mixed case", correctOutput, output); + } +}