diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..0a04128 --- /dev/null +++ b/LICENSE @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/pom.xml b/pom.xml index bab15fd..4891d3a 100644 --- a/pom.xml +++ b/pom.xml @@ -26,7 +26,7 @@ com.mattrixwv cipher-stream-java - 1.3.6-SNAPSHOT + 1.3.6 CipherStreamJava A library to encrypt and decrypt simple ciphers diff --git a/src/main/java/com/mattrixwv/cipherstream/combination/ADFGVX.java b/src/main/java/com/mattrixwv/cipherstream/combination/ADFGVX.java index c273f75..b551ea1 100644 --- a/src/main/java/com/mattrixwv/cipherstream/combination/ADFGVX.java +++ b/src/main/java/com/mattrixwv/cipherstream/combination/ADFGVX.java @@ -1,7 +1,23 @@ //CipherStreamJava/src/main/java/com/mattrixwv/cipherstream/combination/ADFGVX.java //Mattrixwv // Created: 01-26-22 -//Modified: 05-04-23 +//Modified: 08-11-24 +/* + Copyright (C) 2024 Mattrixwv + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ package com.mattrixwv.cipherstream.combination; @@ -15,23 +31,49 @@ import com.mattrixwv.cipherstream.polysubstitution.Columnar; import com.mattrixwv.cipherstream.polysubstitution.LargePolybiusSquare; +/** + * Implements the ADFGVX cipher, which is a combination of a Polybius square and a columnar transposition cipher. + * This class provides methods to encode and decode strings using the ADFGVX cipher. + * + *

+ * The cipher involves two main steps: + *

+ *
    + *
  1. Encoding/decoding with a Polybius square (LargePolybiusSquare)
  2. + *
  3. Encoding/decoding with a columnar transposition cipher (Columnar)
  4. + *
+ */ public class ADFGVX{ private static final Logger logger = LoggerFactory.getLogger(ADFGVX.class); - //Fields - protected String inputString; //The string that needs encoded/decoded - protected String outputString; //The string that is output after encoding/decoding - protected String squareKeyword; //The keyword used in the Polybius Square - protected String keyword; //The Keyword used in the Columnar cipher - //Settings - protected boolean preserveCapitals; //Persist capitals in the output string - protected boolean preserveWhitespace; //Persist whitespace in the output string - protected boolean preserveSymbols; //Persist symbols in the output string - //Internal ciphers - protected LargePolybiusSquare largePolybiusSquare; //The first step in encoding - protected Columnar columnar; //The second step in encoding + //?Fields + /** The string that needs encoded/decoded */ + protected String inputString; + /** The string that is output after encoding/decoding */ + protected String outputString; + /** The keyword used in the Polybius Square */ + protected String squareKeyword; + /** The Keyword used in the Columnar cipher */ + protected String keyword; + //?Settings + /** Persist capitals in the output string */ + protected boolean preserveCapitals; + /** Persist whitespace in the output string */ + protected boolean preserveWhitespace; + /** Persist symbols in the output string */ + protected boolean preserveSymbols; + //?Internal ciphers + /** The first step in encoding */ + protected LargePolybiusSquare largePolybiusSquare; + /** The second step in encoding */ + protected Columnar columnar; - //Ensures Polybius keyword constraints + /** + * Sets the Polybius square keyword and validates it. + * + * @param squareKeyword the keyword for the Polybius square + * @throws InvalidKeywordException if the keyword is null + */ protected void setSquareKeyword(String squareKeyword) throws InvalidKeywordException{ if(squareKeyword == null){ throw new InvalidKeywordException("Square Keyword cannot be null"); @@ -40,7 +82,13 @@ public class ADFGVX{ logger.debug("squareKeyword '{}'", squareKeyword); this.squareKeyword = squareKeyword; } - //Ensures Columnar keyword constraints + + /** + * Sets the columnar cipher keyword and validates it. + * + * @param keyword the keyword for the columnar cipher + * @throws InvalidKeywordException if the keyword is null + */ protected void setKeyword(String keyword) throws InvalidKeywordException{ if(keyword == null){ throw new InvalidKeywordException("Keyword cannot be null"); @@ -49,7 +97,14 @@ public class ADFGVX{ logger.debug("keyword '{}'", keyword); this.keyword = keyword; } - //Ensures inputString constraints + + + /** + * Sets and sanitizes the input string according to the preservation settings. + * + * @param inputString the string to be processed + * @throws InvalidInputException if the input string is null or blank after processing + */ protected void setInputString(String inputString) throws InvalidInputException{ if(inputString == null){ throw new InvalidInputException("Input cannot be null"); @@ -81,7 +136,11 @@ public class ADFGVX{ throw new InvalidInputException("Input cannot be blank"); } } - //Format the output string with capitals, symbols, and numbers that are in the input string + + + /** + * Formats the output string to match the original input string when encoding. + */ protected void formatOutputStringEncode(){ logger.debug("Formatting output string to match input string"); @@ -111,6 +170,9 @@ public class ADFGVX{ outputString = output.toString(); logger.debug("Saving output string '{}'", outputString); } + /** + * Formats the output string to match the original input string when decoding. + */ protected void formatOutputStringDecode(){ logger.debug("Formatting output string to match input string"); @@ -141,7 +203,16 @@ public class ADFGVX{ outputString = output.toString(); logger.debug("Saving output string '{}'", outputString); } - //Encodes the inputString and stores the result in outputString + + /** + * Encodes the input string using the Polybius square and columnar cipher. + * Stores the result in outputString. + * + * @return the encoded string + * @throws InvalidCharacterException if there are invalid characters in the ciphers + * @throws InvalidInputException if the input string is invalid + * @throws InvalidKeywordException if any of the keywords are invalid + */ protected String encode() throws InvalidCharacterException, InvalidInputException, InvalidKeywordException{ //Encode the input with polybius logger.debug("Encoding using Polybius Square"); @@ -160,7 +231,16 @@ public class ADFGVX{ return outputString; } - //Decodes the inputString and stores the result in outputString + + /** + * Decodes the input string using the columnar cipher and Polybius square. + * Stores the result in outputString. + * + * @return the decoded string + * @throws InvalidKeywordException if any of the keywords are invalid + * @throws InvalidCharacterException if there are invalid characters in the ciphers + * @throws InvalidInputException if the input string is invalid + */ protected String decode() throws InvalidKeywordException, InvalidCharacterException, InvalidInputException{ //Decode the input with columnar logger.debug("Decoding using columnar"); @@ -181,13 +261,27 @@ public class ADFGVX{ } - //Constructor + //?Constructor + /** + * Constructs a new {@code ADFGVX} instance with default settings: + * capitals, whitespace, and symbols are not preserved. + * + * @throws InvalidCharacterException if there are invalid characters in the ciphers + */ public ADFGVX() throws InvalidCharacterException{ preserveCapitals = false; preserveWhitespace = false; preserveSymbols = false; reset(); } + /** + * Constructs a new {@code ADFGVX} instance with specified settings for preserving capitals, whitespace, and symbols. + * + * @param preserveCapitals whether to preserve capital letters in the output + * @param preserveWhitespace whether to preserve whitespace in the output + * @param preserveSymbols whether to preserve symbols in the output + * @throws InvalidCharacterException if there are invalid characters in the ciphers + */ public ADFGVX(boolean preserveCapitals, boolean preserveWhitespace, boolean preserveSymbols) throws InvalidCharacterException{ this.preserveCapitals = preserveCapitals; this.preserveWhitespace = preserveWhitespace; @@ -195,14 +289,37 @@ public class ADFGVX{ reset(); } - //Encodes inputString using keyword and returns the result + + /** + * Encodes the provided input string using the specified keywords and returns the encoded result. + * + * @param squareKeyword the keyword for the Polybius square + * @param keyword the keyword for the columnar cipher + * @param inputString the string to be encoded + * @return the encoded string + * @throws InvalidKeywordException if any of the keywords are invalid + * @throws InvalidInputException if the input string is invalid + * @throws InvalidCharacterException if the input contains invalid characters + */ public String encode(String squareKeyword, String keyword, String inputString) throws InvalidKeywordException, InvalidInputException, InvalidCharacterException{ setSquareKeyword(squareKeyword); setKeyword(keyword); setInputString(inputString); return encode(); } - //Decodes inputString using keyword and returns the result + + + /** + * Decodes the provided input string using the specified keywords and returns the decoded result. + * + * @param squareKeyword the keyword for the Polybius square + * @param keyword the keyword for the columnar cipher + * @param inputString the string to be decoded + * @return the decoded string + * @throws InvalidKeywordException if any of the keywords are invalid + * @throws InvalidInputException if the input string is invalid + * @throws InvalidCharacterException if the input contains invalid characters + */ public String decode(String squareKeyword, String keyword, String inputString) throws InvalidKeywordException, InvalidInputException, InvalidCharacterException{ setSquareKeyword(squareKeyword); setKeyword(keyword); @@ -210,20 +327,47 @@ public class ADFGVX{ return decode(); } - //Getters + + //?Getters + /** + * Returns the current input string. + * + * @return the input string + */ public String getInputString(){ return inputString; } + /** + * Returns the current output string. + * + * @return the output string + */ public String getOutputString(){ return outputString; } + /** + * Returns the current Polybius square keyword. + * + * @return the Polybius square keyword + */ public String getSquareKeyword(){ return squareKeyword; } + /** + * Returns the current columnar cipher keyword. + * + * @return the columnar cipher keyword + */ public String getKeyword(){ return keyword; } - //Makes sure all variables are empty + + + /** + * Resets all fields to their default values and re-initializes the internal ciphers. + * + * @throws InvalidCharacterException if there are invalid characters in the ciphers + */ public void reset() throws InvalidCharacterException{ logger.debug("Resetting fields"); diff --git a/src/main/java/com/mattrixwv/cipherstream/combination/ADFGX.java b/src/main/java/com/mattrixwv/cipherstream/combination/ADFGX.java index 08fdcf3..a92824a 100644 --- a/src/main/java/com/mattrixwv/cipherstream/combination/ADFGX.java +++ b/src/main/java/com/mattrixwv/cipherstream/combination/ADFGX.java @@ -1,7 +1,23 @@ //CipherStreamJava/src/main/java/com/mattrixwv/cipherstream/combination/ADFGX.java //Mattrixwv // Created: 01-25-22 -//Modified: 05-04-23 +//Modified: 08-11-24 +/* + Copyright (C) 2024 Mattrixwv + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ package com.mattrixwv.cipherstream.combination; @@ -15,24 +31,50 @@ import com.mattrixwv.cipherstream.polysubstitution.Columnar; import com.mattrixwv.cipherstream.polysubstitution.PolybiusSquare; +/** + * Implements the ADFGX cipher, which is a combination of a Polybius square and a columnar transposition cipher. + * This class provides methods to encode and decode strings using the ADFGX cipher. + * + *

+ * The cipher involves two main steps: + *

+ *
    + *
  1. Encoding/decoding with a Polybius square (PolybiusSquare)
  2. + *
  3. Encoding/decoding with a columnar transposition cipher (Columnar)
  4. + *
+ */ public class ADFGX{ private static final Logger logger = LoggerFactory.getLogger(ADFGX.class); - //Internal fields - protected String inputString; //The string that needs encoded/decoded - protected String outputString; //The string that is output after encoding/decoding - protected String squareKeyword; //The keyword used in the Polybius Square - protected String keyword; //The keyword used in the Columnar cipher - //Settings - protected boolean preserveCapitals; //Persist capitals in the output string - protected boolean preserveWhitespace; //Persist whitespace in the output string - protected boolean preserveSymbols; //Persist symbols in the output string - //Internal ciphers - protected PolybiusSquare polybiusSquare; //The first step in encoding - protected Columnar columnar; //The second step in encoding + //?Internal fields + /** The string that needs encoded/decoded */ + protected String inputString; + /** The string that is output after encoding/decoding */ + protected String outputString; + /** The keyword used in the Polybius Square */ + protected String squareKeyword; + /** The keyword used in the Columnar cipher */ + protected String keyword; + //?Settings + /** Persist capitals in the output string */ + protected boolean preserveCapitals; + /** Persist whitespace in the output string */ + protected boolean preserveWhitespace; + /** Persist symbols in the output string */ + protected boolean preserveSymbols; + //?Internal ciphers + /** The first step in encoding */ + protected PolybiusSquare polybiusSquare; + /** The second step in encoding */ + protected Columnar columnar; - //Ensures Polybius keyword constraints + /** + * Sets the Polybius square keyword and validates it. + * + * @param squareKeyword the keyword for the Polybius square + * @throws InvalidKeywordException if the keyword is null + */ protected void setSquareKeyword(String squareKeyword) throws InvalidKeywordException{ if(squareKeyword == null){ throw new InvalidKeywordException("Square keyword cannot be null"); @@ -41,7 +83,12 @@ public class ADFGX{ logger.debug("Square keyword '{}'", squareKeyword); this.squareKeyword = squareKeyword; } - //Ensures Columnar keyword constraints + /** + * Sets the columnar cipher keyword and validates it. + * + * @param keyword the keyword for the columnar cipher + * @throws InvalidKeywordException if the keyword is null + */ protected void setKeyword(String keyword) throws InvalidKeywordException{ if(keyword == null){ throw new InvalidKeywordException("Keyword cannot be null"); @@ -50,7 +97,12 @@ public class ADFGX{ logger.debug("Keyword '{}'", keyword); this.keyword = keyword; } - //Ensures inputString constraints + /** + * Sets and sanitizes the input string according to the preservation settings. + * + * @param inputString the string to be processed + * @throws InvalidInputException if the input string is null or blank after processing + */ protected void setInputString(String inputString) throws InvalidInputException{ if(inputString == null){ throw new InvalidInputException("Input cannot be null"); @@ -80,7 +132,9 @@ 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 + /** + * Formats the output string to match the original input string when encoding. + */ protected void formatOutputStringEncode(){ logger.debug("Formatting output string to match input string"); @@ -110,6 +164,9 @@ public class ADFGX{ outputString = output.toString(); logger.debug("Saving output string '{}'", outputString); } + /** + * Formats the output string to match the original input string when decoding. + */ protected void formatOutputStringDecode(){ logger.debug("Formatting output string to match input string"); StringBuilder output = new StringBuilder(); @@ -139,7 +196,13 @@ public class ADFGX{ outputString = output.toString(); logger.debug("Saving output string '{}'", outputString); } - //Encodes the inputString and stores the result in outputString + /** + * Encodes the input string using the Polybius square and columnar cipher. + * + * @throws InvalidCharacterException if there are invalid characters in the ciphers + * @throws InvalidInputException if the input string is invalid + * @throws InvalidKeywordException if any of the keywords are invalid + */ protected void encode() throws InvalidCharacterException, InvalidInputException, InvalidKeywordException{ //Encode the input with polybius logger.debug("Encoding using Polybius Square"); @@ -158,7 +221,13 @@ public class ADFGX{ //Add whatever is needed to the output string formatOutputStringEncode(); } - //Decodes the inputString and stores the result in outputString + /** + * Decodes the input string using the columnar cipher and Polybius square. + * + * @throws InvalidKeywordException if any of the keywords are invalid + * @throws InvalidCharacterException if there are invalid characters in the ciphers + * @throws InvalidInputException if the input string is invalid + */ protected void decode() throws InvalidKeywordException, InvalidCharacterException, InvalidInputException{ //Decode the input with columnar logger.debug("Decoding using columnar"); @@ -179,13 +248,27 @@ public class ADFGX{ } - //Constructor + //?Constructor + /** + * Constructs a new {@code ADFGX} instance with default settings: + * capitals, whitespace, and symbols are not preserved. + * + * @throws InvalidCharacterException if there are invalid characters in the ciphers + */ public ADFGX() throws InvalidCharacterException{ preserveCapitals = false; preserveWhitespace = false; preserveSymbols = false; reset(); } + /** + * Constructs a new {@code ADFGX} instance with specified settings for preserving capitals, whitespace, and symbols. + * + * @param preserveCapitals whether to preserve capital letters in the output + * @param preserveWhitespace whether to preserve whitespace in the output + * @param preserveSymbols whether to preserve symbols in the output + * @throws InvalidCharacterException if there are invalid characters in the ciphers + */ public ADFGX(boolean preserveCapitals, boolean preserveWhitespace, boolean preserveSymbols) throws InvalidCharacterException{ this.preserveCapitals = preserveCapitals; this.preserveWhitespace = preserveWhitespace; @@ -193,7 +276,17 @@ public class ADFGX{ reset(); } - //Encodes inputString using keyword and returns the result + /** + * Encodes the provided input string using the specified keywords and returns the encoded result. + * + * @param squareKeyword the keyword for the Polybius square + * @param keyword the keyword for the columnar cipher + * @param inputString the string to be encoded + * @return the encoded string + * @throws InvalidKeywordException if any of the keywords are invalid + * @throws InvalidInputException if the input string is invalid + * @throws InvalidCharacterException if the input contains invalid characters + */ public String encode(String squareKeyword, String keyword, String inputString) throws InvalidKeywordException, InvalidInputException, InvalidCharacterException{ setSquareKeyword(squareKeyword); setKeyword(keyword); @@ -201,7 +294,17 @@ public class ADFGX{ encode(); return outputString; } - //Decodes inputString using keyword and returns the result + /** + * Decodes the provided input string using the specified keywords and returns the decoded result. + * + * @param squareKeyword the keyword for the Polybius square + * @param keyword the keyword for the columnar cipher + * @param inputString the string to be decoded + * @return the decoded string + * @throws InvalidKeywordException if any of the keywords are invalid + * @throws InvalidInputException if the input string is invalid + * @throws InvalidCharacterException if the input contains invalid characters + */ public String decode(String squareKeyword, String keyword, String inputString) throws InvalidKeywordException, InvalidInputException, InvalidCharacterException{ setSquareKeyword(squareKeyword); setKeyword(keyword); @@ -210,20 +313,44 @@ public class ADFGX{ return outputString; } - //Getters + //?Getters + /** + * Returns the current input string. + * + * @return the input string + */ public String getInputString(){ return inputString; } + /** + * Returns the current output string. + * + * @return the output string + */ public String getOutputString(){ return outputString; } + /** + * Returns the current Polybius square keyword. + * + * @return the Polybius square keyword + */ public String getSquareKeyword(){ return squareKeyword; } + /** + * Returns the current columnar cipher keyword. + * + * @return the columnar cipher keyword + */ public String getKeyword(){ return keyword; } - //Makes sure all variables are empty + /** + * Resets all fields to their default values and reinitializes the internal ciphers. + * + * @throws InvalidCharacterException if there are invalid characters in the ciphers + */ public void reset() throws InvalidCharacterException{ logger.debug("Resetting fields"); diff --git a/src/main/java/com/mattrixwv/cipherstream/exceptions/InvalidBaseException.java b/src/main/java/com/mattrixwv/cipherstream/exceptions/InvalidBaseException.java index f4911be..778de57 100644 --- a/src/main/java/com/mattrixwv/cipherstream/exceptions/InvalidBaseException.java +++ b/src/main/java/com/mattrixwv/cipherstream/exceptions/InvalidBaseException.java @@ -1,20 +1,58 @@ //CipherStreamJava/src/main/java/com/mattrixwv/CipherStreamJava/Exceptions/InvalidBaseException.java //Mattrixwv // Created: 01-09-22 -//Modified: 01-09-22 +//Modified: 08-11-24 +/* + Copyright (C) 2024 Mattrixwv + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ package com.mattrixwv.cipherstream.exceptions; +/** + * Thrown to indicate that a problem has occurred related to the base or group size. + */ public class InvalidBaseException extends RuntimeException{ + /** + * Constructs a new {@code InvalidBaseException} with {@code null} as its detail message. + */ public InvalidBaseException(){ super(); } + /** + * Constructs a new {@code InvalidBaseException} with the specified detail message. + * + * @param message the detail message, which is saved for later retrieval by the {@link #getMessage()} method + */ public InvalidBaseException(String message){ super(message); } + /** + * Constructs a new {@code InvalidBaseException} with the specified cause. + * + * @param error the cause, which is saved for later retrieval by the {@link #getCause()} method + */ public InvalidBaseException(Throwable error){ super(error); } + /** + * Constructs a new {@code InvalidBaseException} with the specified detail message and cause. + * + * @param message the detail message, which is saved for later retrieval by the {@link #getMessage()} method + * @param error the cause, which is saved for later retrieval by the {@link #getCause()} method + */ public InvalidBaseException(String message, Throwable error){ super(message, error); } diff --git a/src/main/java/com/mattrixwv/cipherstream/exceptions/InvalidCharacterException.java b/src/main/java/com/mattrixwv/cipherstream/exceptions/InvalidCharacterException.java index c461908..fb4e62d 100644 --- a/src/main/java/com/mattrixwv/cipherstream/exceptions/InvalidCharacterException.java +++ b/src/main/java/com/mattrixwv/cipherstream/exceptions/InvalidCharacterException.java @@ -1,20 +1,58 @@ //CipherStreamJava/src/main/java/com/mattrixwv/CipherStreamJava/Exceptions/InvalidCharacterException.java //Mattrixwv // Created: 01-04-22 -//Modified: 01-04-22 +//Modified: 08-11-24 +/* + Copyright (C) 2024 Mattrixwv + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ package com.mattrixwv.cipherstream.exceptions; +/** + * Thrown to indicate that a problem has occurred related to an invalid character. + */ public class InvalidCharacterException extends RuntimeException{ + /** + * Constructs a new {@code InvalidCharacterException} with {@code null} as its detail message. + */ public InvalidCharacterException(){ super(); } + /** + * Constructs a new {@code InvalidCharacterException} with the specified detail message. + * + * @param message the detail message, which is saved for later retrieval by the {@link #getMessage()} method + */ public InvalidCharacterException(String message){ super(message); } + /** + * Constructs a new {@code InvalidCharacterException} with the specified cause. + * + * @param error the cause, which is saved for later retrieval by the {@link #getCause()} method + */ public InvalidCharacterException(Throwable error){ super(error); } + /** + * Constructs a new {@code InvalidCharacterException} with the specified detail message and cause. + * + * @param message the detail message, which is saved for later retrieval by the {@link #getMessage()} method + * @param error the cause, which is saved for later retrieval by the {@link #getCause()} method + */ public InvalidCharacterException(String message, Throwable error){ super(message, error); } diff --git a/src/main/java/com/mattrixwv/cipherstream/exceptions/InvalidInputException.java b/src/main/java/com/mattrixwv/cipherstream/exceptions/InvalidInputException.java index 5da1dd0..96d7482 100644 --- a/src/main/java/com/mattrixwv/cipherstream/exceptions/InvalidInputException.java +++ b/src/main/java/com/mattrixwv/cipherstream/exceptions/InvalidInputException.java @@ -1,20 +1,58 @@ //CipherStreamJava/src/main/java/com/mattrixwv/CipherStreamJava/Exceptions/InvalidInputException.java //Mattrixwv // Created: 01-09-22 -//Modified: 01-09-22 +//Modified: 08-11-24 +/* + Copyright (C) 2024 Mattrixwv + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ package com.mattrixwv.cipherstream.exceptions; +/** + * Thrown to indicate that a problem has occurred related to invalid input. + */ public class InvalidInputException extends RuntimeException{ + /** + * Constructs a new {@code InvalidInputException} with {@code null} as its detail message. + */ public InvalidInputException(){ super(); } + /** + * Constructs a new {@code InvalidInputException} with the specified detail message. + * + * @param message the detail message, which is saved for later retrieval by the {@link #getMessage()} method + */ public InvalidInputException(String message){ super(message); } + /** + * Constructs a new {@code InvalidInputException} with the specified cause. + * + * @param error the cause, which is saved for later retrieval by the {@link #getCause()} method + */ public InvalidInputException(Throwable error){ super(error); } + /** + * Constructs a new {@code InvalidInputException} with the specified detail message and cause. + * + * @param message the detail message, which is saved for later retrieval by the {@link #getMessage()} method + * @param error the cause, which is saved for later retrieval by the {@link #getCause()} method + */ public InvalidInputException(String message, Throwable error){ super(message, error); } diff --git a/src/main/java/com/mattrixwv/cipherstream/exceptions/InvalidKeyException.java b/src/main/java/com/mattrixwv/cipherstream/exceptions/InvalidKeyException.java index 521355d..dd7946a 100644 --- a/src/main/java/com/mattrixwv/cipherstream/exceptions/InvalidKeyException.java +++ b/src/main/java/com/mattrixwv/cipherstream/exceptions/InvalidKeyException.java @@ -1,20 +1,58 @@ //CipherStreamJava/src/main/java/com/mattrixwv/cipherstream/exceptions/InvalidKeyException.java //Matrixwv // Created: 07-09-22 -//Modified: 07-09-22 +//Modified: 08-11-24 +/* + Copyright (C) 2024 Mattrixwv + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ package com.mattrixwv.cipherstream.exceptions; +/** + * Thrown to indicate that a problem has occurred related to an invalid key. + */ public class InvalidKeyException extends RuntimeException{ + /** + * Constructs a new {@code InvalidKeyException} with {@code null} as its detail message. + */ public InvalidKeyException(){ super(); } + /** + * Constructs a new {@code InvalidKeyException} with the specified detail message. + * + * @param message the detail message, which is saved for later retrieval by the {@link #getMessage()} method + */ public InvalidKeyException(String message){ super(message); } + /** + * Constructs a new {@code InvalidKeyException} with the specified cause. + * + * @param error the cause, which is saved for later retrieval by the {@link #getCause()} method + */ public InvalidKeyException(Throwable error){ super(error); } + /** + * Constructs a new {@code InvalidKeyException} with the specified detail message and cause. + * + * @param message the detail message, which is saved for later retrieval by the {@link #getMessage()} method + * @param error the cause, which is saved for later retrieval by the {@link #getCause()} method + */ public InvalidKeyException(String message, Throwable error){ super(message, error); } diff --git a/src/main/java/com/mattrixwv/cipherstream/exceptions/InvalidKeywordException.java b/src/main/java/com/mattrixwv/cipherstream/exceptions/InvalidKeywordException.java index 4b2360c..5a8de5c 100644 --- a/src/main/java/com/mattrixwv/cipherstream/exceptions/InvalidKeywordException.java +++ b/src/main/java/com/mattrixwv/cipherstream/exceptions/InvalidKeywordException.java @@ -1,20 +1,58 @@ //CipherStreamJava/src/main/java/com/mattrixwv/CipherStreamJava/Exceptions/InvalidKeywordException.java //Mattrixwv // Created: 01-09-22 -//Modified: 01-09-22 +//Modified: 08-11-24 +/* + Copyright (C) 2024 Mattrixwv + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ package com.mattrixwv.cipherstream.exceptions; +/** + * Thrown to indicate that a problem has occurred related to an invalid keyword. + */ public class InvalidKeywordException extends RuntimeException{ + /** + * Constructs a new {@code InvalidKeywordException} with {@code null} as its detail message. + */ public InvalidKeywordException(){ super(); } + /** + * Constructs a new {@code InvalidKeywordException} with the specified detail message. + * + * @param message the detail message, which is saved for later retrieval by the {@link #getMessage()} method + */ public InvalidKeywordException(String message){ super(message); } + /** + * Constructs a new {@code InvalidKeywordException} with the specified cause. + * + * @param error the cause, which is saved for later retrieval by the {@link #getCause()} method + */ public InvalidKeywordException(Throwable error){ super(error); } + /** + * Constructs a new {@code InvalidKeywordException} with the specified detail message and cause. + * + * @param message the detail message, which is saved for later retrieval by the {@link #getMessage()} method + * @param error the cause, which is saved for later retrieval by the {@link #getCause()} method + */ public InvalidKeywordException(String message, Throwable error){ super(message, error); } diff --git a/src/main/java/com/mattrixwv/cipherstream/monosubstitution/Affine.java b/src/main/java/com/mattrixwv/cipherstream/monosubstitution/Affine.java index 8bf1679..5ea97a1 100644 --- a/src/main/java/com/mattrixwv/cipherstream/monosubstitution/Affine.java +++ b/src/main/java/com/mattrixwv/cipherstream/monosubstitution/Affine.java @@ -1,7 +1,23 @@ //CipherStreamJava/src/main/java/com/mattrixwv/cipherstream/polysubstitution/Affine.java //Mattrixwv // Created: 01-26-22 -//Modified: 05-04-23 +//Modified: 08-11-24 +/* + Copyright (C) 2024 Mattrixwv + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ package com.mattrixwv.cipherstream.monosubstitution; @@ -13,20 +29,44 @@ import com.mattrixwv.cipherstream.exceptions.InvalidInputException; import com.mattrixwv.cipherstream.exceptions.InvalidKeywordException; +/** + * Implements the Affine cipher, which is a monoalphabetic substitution cipher based on linear algebra. + * This class provides methods to encode and decode strings using the Affine cipher with a specified key. + * + *

+ * The Affine cipher uses two keys: + *

+ *
    + *
  • Key1: The multiplicative key (must be relatively prime to 26)
  • + *
  • Key2: The additive key
  • + *
+ */ public class Affine{ private static final Logger logger = LoggerFactory.getLogger(Affine.class); - //Fields - protected String inputString; //The string that needs encoded/decoded - protected String outputString; //The string that is output after encoding/decoding - protected int key1; //The multiplicative key. Key1 must be relatively prime to 26 - protected int key2; //The additive key - //Settings - protected boolean preserveCapitals; //Persist capitals in the output string - protected boolean preserveSymbols; //Persist symbols in the output string - protected boolean preserveWhitespace; //Persist whitespace in the output string + //?Fields + /** The string that needs encoded/decoded */ + protected String inputString; + /** The string that is output after encoding/decoding */ + protected String outputString; + /** The multiplicative key. Key1 must be relatively prime to 26 */ + protected int key1; + /** The additive key */ + protected int key2; + //?Settings + /** Persist capitals in the output string */ + protected boolean preserveCapitals; + /** Persist symbols in the output string */ + protected boolean preserveSymbols; + /** Persist whitespace in the output string */ + protected boolean preserveWhitespace; - //Ensures key1 constraints + /** + * Sets the multiplicative key and validates it. + * + * @param key1 the multiplicative key + * @throws InvalidKeywordException if the key1 is not relatively prime to 26 + */ protected void setKey1(int key1) throws InvalidKeywordException{ logger.debug("Setting key1 {}", key1); @@ -48,7 +88,11 @@ public class Affine{ logger.debug("Cleaned key1 {}", key1); } - //Ensures key2 constraints + /** + * Sets the additive key. + * + * @param key2 the additive key + */ protected void setKey2(int key2){ logger.debug("Setting key2 {}", key2); @@ -65,7 +109,12 @@ public class Affine{ logger.debug("Cleaned key2 {}", key2); } - //Ensures inputString constraints + /** + * Sets and sanitizes the input string according to the preservation settings. + * + * @param inputString the string to be processed + * @throws InvalidInputException if the input string is null or blank after processing + */ protected void setInputString(String inputString) throws InvalidInputException{ if(inputString == null){ throw new InvalidInputException("Input must not be null"); @@ -97,7 +146,9 @@ public class Affine{ throw new InvalidInputException("Input cannot be blank"); } } - //Encodes the inputString and stores the result in outputString + /** + * Encodes the input string using the affine cipher. + */ protected void encode(){ logger.debug("Encoding"); @@ -138,7 +189,9 @@ public class Affine{ outputString = output.toString(); logger.debug("Saving output string '{}'", outputString); } - //Decodes the inputString and stores the result in outputString + /** + * Decodes the input string using the affine cipher. + */ protected void decode(){ logger.debug("Decoding"); @@ -194,13 +247,24 @@ public class Affine{ } - //Constructor + //?Constructor + /** + * Constructs a new {@code Affine} instance with default settings: + * capitals, symbols, and whitespace are not preserved. + */ public Affine(){ preserveCapitals = false; preserveSymbols = false; preserveWhitespace = false; reset(); } + /** + * Constructs a new {@code Affine} instance with specified settings for preserving capitals, symbols, and whitespace. + * + * @param preserveCapitals whether to preserve capital letters in the output + * @param preserveWhitespace whether to preserve whitespace in the output + * @param preserveSymbols whether to preserve symbols in the output + */ public Affine(boolean preserveCapitals, boolean preserveWhitespace, boolean preserveSymbols){ this.preserveCapitals = preserveCapitals; this.preserveSymbols = preserveSymbols; @@ -208,7 +272,16 @@ public class Affine{ reset(); } - //Encodes inputString using key1 and key2 and returns the result + /** + * Encodes the provided input string using the specified keys and returns the encoded result. + * + * @param key1 the multiplicative key (must be relatively prime to 26) + * @param key2 the additive key + * @param inputString the string to be encoded + * @return the encoded string + * @throws InvalidKeywordException if key1 is not relatively prime to 26 + * @throws InvalidInputException if the input string is invalid + */ public String encode(int key1, int key2, String inputString) throws InvalidKeywordException, InvalidInputException{ setKey1(key1); setKey2(key2); @@ -216,7 +289,16 @@ public class Affine{ encode(); return outputString; } - //Decodes inputString using key1 and key2 and returns the result + /** + * Decodes the provided input string using the specified keys and returns the decoded result. + * + * @param key1 the multiplicative key (must be relatively prime to 26) + * @param key2 the additive key + * @param inputString the string to be decoded + * @return the decoded string + * @throws InvalidKeywordException if key1 is not relatively prime to 26 + * @throws InvalidInputException if the input string is invalid + */ public String decode(int key1, int key2, String inputString) throws InvalidKeywordException, InvalidInputException{ setKey1(key1); setKey2(key2); @@ -225,20 +307,42 @@ public class Affine{ return outputString; } - //Getters + //?Getters + /** + * Returns the current input string. + * + * @return the input string + */ public String getInputString(){ return inputString; } + /** + * Returns the current output string. + * + * @return the output string + */ public String getOutputString(){ return outputString; } + /** + * Returns the current multiplicative key. + * + * @return the multiplicative key + */ public int getKey1(){ return key1; } + /** + * Returns the current additive key. + * + * @return the additive key + */ public int getKey2(){ return key2; } - //Makes sure all of the variables are empty + /** + * Resets all fields to their default values. + */ public void reset(){ logger.debug("Resetting fields"); diff --git a/src/main/java/com/mattrixwv/cipherstream/monosubstitution/Atbash.java b/src/main/java/com/mattrixwv/cipherstream/monosubstitution/Atbash.java index f4685ce..f410960 100644 --- a/src/main/java/com/mattrixwv/cipherstream/monosubstitution/Atbash.java +++ b/src/main/java/com/mattrixwv/cipherstream/monosubstitution/Atbash.java @@ -1,7 +1,23 @@ //CipherStreamJava/src/main/java/com/mattrixwv/cipherstream/monosubstitution/Atbash.java //Mattrixwv // Created: 07-25-21 -//Modified: 05-04-23 +//Modified: 08-11-24 +/* + Copyright (C) 2024 Mattrixwv + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ package com.mattrixwv.cipherstream.monosubstitution; @@ -11,18 +27,34 @@ import org.slf4j.LoggerFactory; import com.mattrixwv.cipherstream.exceptions.InvalidInputException; +/** + * Implements the Atbash cipher, a simple substitution cipher where each letter of the alphabet is mapped to its reverse. + * For example, 'A' is mapped to 'Z', 'B' to 'Y', and so on. + * This class provides methods to encode and decode strings using the Atbash cipher. + * + *

+ * The Atbash cipher is symmetric, meaning that encoding and decoding are the same operation. + *

+ */ public class Atbash{ private static final Logger logger = LoggerFactory.getLogger(Atbash.class); - //Fields - protected String inputString; //Holds the string that needs encoded or decoded - protected String outputString; //The encoded/decoded string - //Settings - protected boolean preserveCapitals; //Persist capitals in the output string - protected boolean preserveWhitespace; //Persist whitespace in the output string - protected boolean preserveSymbols; //Persist symbols in the output string + //?Fields + /** Holds the string that needs encoded or decoded */ + protected String inputString; + /** The encoded/decoded string */ + protected String outputString; + //?Settings + /** Persist capitals in the output string */ + protected boolean preserveCapitals; + /** Persist whitespace in the output string */ + protected boolean preserveWhitespace; + /** Persist symbols in the output string */ + protected boolean preserveSymbols; - //Encodes inputString and stores in outputString + /** + * Encodes the input string using the Atbash cipher. + */ protected void encode(){ logger.debug("Encoding"); StringBuilder output = new StringBuilder(); @@ -57,7 +89,12 @@ public class Atbash{ outputString = output.toString(); logger.debug("Saving output string '{}'", outputString); } - //Removes all invalid characters and sets inputString + /** + * Sets and sanitizes the input string according to the preservation settings. + * + * @param inputString the string to be processed + * @throws InvalidInputException if the input string is null or blank after processing + */ protected void setInputString(String inputString) throws InvalidInputException{ if(inputString == null){ throw new InvalidInputException("Input cannot be null"); @@ -95,13 +132,24 @@ public class Atbash{ } - //Constructor + //?Constructor + /** + * Constructs a new {@code Atbash} instance with default settings: + * capitals, symbols, and whitespace are not preserved. + */ public Atbash(){ reset(); preserveCapitals = false; preserveWhitespace = false; preserveSymbols = false; } + /** + * Constructs a new {@code Atbash} instance with specified settings for preserving capitals, whitespace, and symbols. + * + * @param preserveCapitals whether to preserve capital letters in the output + * @param preserveWhitespace whether to preserve whitespace in the output + * @param preserveSymbols whether to preserve symbols in the output + */ public Atbash(boolean preserveCapitals, boolean preserveWhitespace, boolean preserveSymbols){ reset(); this.preserveCapitals = preserveCapitals; @@ -109,7 +157,13 @@ public class Atbash{ this.preserveSymbols = preserveSymbols; } - //Encodes inputString and returns the result + /** + * Encodes the provided input string using the Atbash cipher and returns the encoded result. + * + * @param inputString the string to be encoded + * @return the encoded string + * @throws InvalidInputException if the input string is invalid + */ public String encode(String inputString) throws InvalidInputException{ //Make sure everything is empty before you begin reset(); @@ -117,19 +171,38 @@ public class Atbash{ encode(); return outputString; } - //Decodes inputString and returns the result + /** + * Decodes the provided input string using the Atbash cipher and returns the decoded result. + * Since the Atbash cipher is symmetric, this method performs the same operation as encoding. + * + * @param inputString the string to be decoded + * @return the decoded string + * @throws InvalidInputException if the input string is invalid + */ public String decode(String inputString) throws InvalidInputException{ return encode(inputString); } - //Getters + //?Getters + /** + * Returns the current input string. + * + * @return the input string + */ public String getInputString(){ return inputString; } + /** + * Returns the current output string. + * + * @return the output string + */ public String getOutputString(){ return outputString; } - //Makes sure all variables are empty + /** + * Resets all fields to their default values. + */ public void reset(){ logger.debug("Resetting fields"); diff --git a/src/main/java/com/mattrixwv/cipherstream/monosubstitution/Autokey.java b/src/main/java/com/mattrixwv/cipherstream/monosubstitution/Autokey.java index 821644d..f75f695 100644 --- a/src/main/java/com/mattrixwv/cipherstream/monosubstitution/Autokey.java +++ b/src/main/java/com/mattrixwv/cipherstream/monosubstitution/Autokey.java @@ -1,7 +1,23 @@ //CipherStreamJava/src/main/java/com/mattrixwv/CipherStreamJava/Autokey.java //Mattrixwv // Created: 07-25-21 -//Modified: 05-04-23 +//Modified: 08-11-24 +/* + Copyright (C) 2024 Mattrixwv + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ package com.mattrixwv.cipherstream.monosubstitution; @@ -12,11 +28,28 @@ import com.mattrixwv.cipherstream.exceptions.InvalidInputException; import com.mattrixwv.cipherstream.exceptions.InvalidKeywordException; +/** + * Implements the Autokey cipher, an extension of the Vigenère cipher that uses a keyword combined with the plaintext itself as the key. + * The Autokey cipher adds the plaintext to the end of the keyword to create a longer key, which helps to make the encryption stronger. + * This class inherits from the {@code Vigenere} class and overrides methods to handle encoding and decoding with the Autokey cipher. + * + *

+ * The Autokey cipher is symmetric, meaning that encoding and decoding are essentially the same process, but with a different key setup for decoding. + *

+ */ public class Autokey extends Vigenere{ private static final Logger logger = LoggerFactory.getLogger(Autokey.class); - //Special rules for setting the strings for encoding + /** + * Sets up the keyword and input string for encoding, generating a longer key that includes the plaintext. + * This method is used internally to prepare the cipher for encoding. + * + * @param keyword the keyword used for encoding + * @param inputString the string to be encoded + * @throws InvalidKeywordException if the keyword is invalid + * @throws InvalidInputException if the input string is invalid + */ protected void encodeSet(String keyword, String inputString) throws InvalidKeywordException, InvalidInputException{ logger.debug("Setting fields for encoding"); @@ -44,7 +77,15 @@ public class Autokey extends Vigenere{ offset.clear(); setOffset(); } - //Setting the strings for decoding + /** + * Sets up the keyword and input string for decoding. The keyword is used to decode the input string. + * This method is used internally to prepare the cipher for decoding. + * + * @param keyword the keyword used for decoding + * @param inputString the string to be decoded + * @throws InvalidKeywordException if the keyword is invalid + * @throws InvalidInputException if the input string is invalid + */ protected void decodeSet(String keyword, String inputString) throws InvalidKeywordException, InvalidInputException{ logger.debug("Setting fields for decoding"); @@ -56,7 +97,10 @@ public class Autokey extends Vigenere{ logger.debug("Setting input string"); setInputString(inputString); } - //Decodes the inputString + /** + * Decodes the input string using the Autokey cipher. + * This method is overridden to handle decoding with the Autokey cipher, which involves using the key and updating it with decoded characters. + */ @Override protected void decode(){ logger.debug("Decoding"); @@ -113,14 +157,32 @@ public class Autokey extends Vigenere{ } - //Constructor + //?Constructor + /** + * Constructs a new {@code Autokey} instance with default settings for preserving capitals, whitespace, and symbols. + */ public Autokey(){ super(); } + /** + * Constructs a new {@code Autokey} instance with specified settings for preserving capitals, whitespace, and symbols. + * + * @param preserveCapitals whether to preserve capital letters in the output + * @param preserveWhitespace whether to preserve whitespace in the output + * @param preserveSymbols whether to preserve symbols in the output + */ public Autokey(boolean preserveCapitals, boolean preserveWhitespace, boolean preserveSymbols){ super(preserveCapitals, preserveWhitespace, preserveSymbols); } - //Encodes inputString using the Autokey cipher + /** + * Encodes the input string using the Autokey cipher with the provided keyword. + * + * @param keyword the keyword used for encoding + * @param inputString the string to be encoded + * @return the encoded string + * @throws InvalidKeywordException if the keyword is invalid + * @throws InvalidInputException if the input string is invalid + */ @Override public String encode(String keyword, String inputString) throws InvalidKeywordException, InvalidInputException{ reset(); @@ -128,7 +190,15 @@ public class Autokey extends Vigenere{ encode(); return outputString; } - //Decodes inputString using the Autokey cipher + /** + * Decodes the input string using the Autokey cipher with the provided keyword. + * + * @param keyword the keyword used for decoding + * @param inputString the string to be decoded + * @return the decoded string + * @throws InvalidKeywordException if the keyword is invalid + * @throws InvalidInputException if the input string is invalid + */ @Override public String decode(String keyword, String inputString) throws InvalidKeywordException, InvalidInputException{ reset(); diff --git a/src/main/java/com/mattrixwv/cipherstream/monosubstitution/Baconian.java b/src/main/java/com/mattrixwv/cipherstream/monosubstitution/Baconian.java index 8b5ca05..3b7e9e1 100644 --- a/src/main/java/com/mattrixwv/cipherstream/monosubstitution/Baconian.java +++ b/src/main/java/com/mattrixwv/cipherstream/monosubstitution/Baconian.java @@ -1,7 +1,23 @@ //CipherStreamJava/src/test/java/com/mattrixwv/CipherStreamJava/Baconian.java //Mattrixwv // Created: 01-12-22 -//Modified: 04-19-24 +//Modified: 08-11-24 +/* + Copyright (C) 2024 Mattrixwv + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ package com.mattrixwv.cipherstream.monosubstitution; @@ -16,20 +32,38 @@ import com.mattrixwv.cipherstream.exceptions.InvalidCharacterException; import com.mattrixwv.cipherstream.exceptions.InvalidInputException; +/** + * Implements the Baconian cipher, a method of steganography where each letter of the alphabet is represented by a unique sequence of five characters ('a' or 'b'). + * The Baconian cipher is a simple substitution cipher that can encode and decode text based on these sequences. + * + *

+ * The cipher uses a predefined list of five-character strings to represent each letter of the alphabet (A-Z). The input string is converted to these sequences for encoding, + * and sequences are converted back to letters for decoding. + *

+ */ public class Baconian{ private static final Logger logger = LoggerFactory.getLogger(Baconian.class); - //Conversions + //?Conversions + /** Predefined code for Baconian cipher (5-character strings for A-Z) */ protected static final ArrayList code = new ArrayList<>(Arrays.asList( "aaaaa", "aaaab", "aaaba", "aaabb", "aabaa", "aabab", "aabba","aabbb", "abaaa", "abaaa", "abaab", "ababa", "ababb", //A-M "abbaa", "abbab", "abbba", "abbbb", "baaaa", "baaab", "baaba", "baabb", "baabb", "babaa", "babab", "babba", "babbb" //N-Z )); - protected String inputString; //The string that needs encoded/decoded - protected String outputString; //The encoded/decoded string - protected boolean preserveCapitals; //Persist capitals in the output string + /** The string that needs encoded/decoded */ + protected String inputString; + /** The encoded/decoded string */ + protected String outputString; + /** Persist capitals in the output string */ + protected boolean preserveCapitals; - //Sets the input string + /** + * Sets the input string for encoding, removing whitespace and symbols, and handling capitalization based on the flag. + * + * @param inputString the string to be encoded + * @throws InvalidInputException if the input string is null, empty, or invalid + */ protected void setInputStringEncode(String inputString) throws InvalidInputException{ if(inputString == null){ throw new InvalidInputException("Input cannot be null"); @@ -53,6 +87,13 @@ public class Baconian{ throw new InvalidInputException("Input must contain at least 1 letter"); } } + /** + * Sets the input string for decoding, ensuring it contains only valid Baconian characters (a's and b's) with a length of 5. + * + * @param inputString the string to be decoded + * @throws InvalidCharacterException if the input string contains invalid Baconian characters + * @throws InvalidInputException if the input string is null or empty + */ protected void setInputStringDecode(String inputString) throws InvalidCharacterException, InvalidInputException{ if(inputString == null){ throw new InvalidInputException("Input cannot be null"); @@ -91,7 +132,10 @@ public class Baconian{ logger.debug("Cleaned input string '{}'", inputString); } - //Encodes the inputString and stores the result in outputString + /** + * Encodes the input string using the Baconian cipher. + * Each character in the input string is converted to its corresponding Baconian sequence. + */ protected void encode(){ logger.debug("Encoding"); StringJoiner output = new StringJoiner(" "); @@ -121,7 +165,10 @@ public class Baconian{ outputString = output.toString(); logger.debug("Saving output string '{}'", outputString); } - //Decodes the inputString and stores the result in outputString + /** + * Decodes the input string using the Baconian cipher. + * Each Baconian sequence in the input string is converted back to its corresponding character. + */ protected void decode(){ logger.debug("Decoding"); @@ -157,24 +204,45 @@ public class Baconian{ logger.debug("Saving output string '{}'", outputString); } - //Constructor + //?Constructor + /** + * Constructs a new {@code Baconian} instance with default settings for preserving capitals. + */ public Baconian(){ reset(); preserveCapitals = false; } + /** + * Constructs a new {@code Baconian} instance with a specified setting for preserving capitals. + * + * @param preserveCapitals whether to preserve capital letters in the output + */ public Baconian(boolean preserveCapitals){ reset(); this.preserveCapitals = preserveCapitals; } - //Sets the inputString and encodes the message + /** + * Encodes the input string using the Baconian cipher. + * + * @param inputString the string to be encoded + * @return the encoded string + * @throws InvalidInputException if the input string is invalid + */ public String encode(String inputString) throws InvalidInputException{ reset(); setInputStringEncode(inputString); encode(); return outputString; } - //Sets the inputString and decodes the message + /** + * Decodes the input string using the Baconian cipher. + * + * @param inputString the string to be decoded + * @return the decoded string + * @throws InvalidCharacterException if the input string contains invalid Baconian characters + * @throws InvalidInputException if the input string is invalid + */ public String decode(String inputString) throws InvalidCharacterException, InvalidInputException{ reset(); setInputStringDecode(inputString); @@ -182,14 +250,26 @@ public class Baconian{ return outputString; } - //Getters + //?Getters + /** + * Gets the current input string. + * + * @return the input string + */ public String getInputString(){ return inputString; } + /** + * Gets the current output string. + * + * @return the output string + */ public String getOutputString(){ return outputString; } - //Makes sure all variables are empty + /** + * Resets the input and output strings to empty. + */ public void reset(){ logger.debug("Resetting fields"); diff --git a/src/main/java/com/mattrixwv/cipherstream/monosubstitution/BaseX.java b/src/main/java/com/mattrixwv/cipherstream/monosubstitution/BaseX.java index 75afe23..e23c335 100644 --- a/src/main/java/com/mattrixwv/cipherstream/monosubstitution/BaseX.java +++ b/src/main/java/com/mattrixwv/cipherstream/monosubstitution/BaseX.java @@ -1,7 +1,23 @@ //CipherStreamJava/src/main/java/com/mattrixwv/cipherstream/monosubstitution/BaseX.java //Mattrixwv // Created: 01-08-22 -//Modified: 05-04-23 +//Modified: 08-11-24 +/* + Copyright (C) 2024 Mattrixwv + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ package com.mattrixwv.cipherstream.monosubstitution; @@ -15,16 +31,35 @@ import com.mattrixwv.cipherstream.exceptions.InvalidCharacterException; import com.mattrixwv.cipherstream.exceptions.InvalidInputException; +/** + * A class for encoding and decoding strings using a specified numerical base. + * The BaseX class allows encoding and decoding of strings where characters are represented in a given base. + * The base can be set to any value between Character.MIN_RADIX and Character.MAX_RADIX. + * + *

+ * This class supports encoding and decoding of ASCII characters into their base-X representations, + * where X is the base provided by the user. It ensures that input strings are valid and within the acceptable range + * for the specified base. + *

+ */ public class BaseX{ private static final Logger logger = LoggerFactory.getLogger(BaseX.class); - //Fields - protected String inputString; //The string that needs encoded/decoded - protected String outputString; //The encoded/decoded string - //Settings - protected int base; //The base that the number will be encoded at + //?Fields + /** The string that needs encoded/decoded */ + protected String inputString; + /** The encoded/decoded string */ + protected String outputString; + //?Settings + /** The base that the number will be encoded at */ + protected int base; - //Sets the input string + /** + * Sets the input string for encoding, ensuring it is not null and contains at least one letter. + * + * @param inputString the string to be encoded + * @throws InvalidInputException if the input string is null or blank + */ protected void setInputStringEncode(String inputString) throws InvalidInputException{ if(inputString == null){ throw new InvalidInputException("Input cannot be null"); @@ -38,6 +73,13 @@ public class BaseX{ throw new InvalidInputException("Input must contain at least 1 letter"); } } + /** + * Sets the input string for decoding, ensuring it is not null, does not contain invalid characters, and is properly formatted. + * + * @param inputString the string to be decoded + * @throws InvalidCharacterException if the input string contains invalid characters + * @throws InvalidInputException if the input string is null or blank + */ protected void setInputStringDecode(String inputString) throws InvalidCharacterException, InvalidInputException{ if(inputString == null){ throw new InvalidInputException("Input cannot be null"); @@ -68,7 +110,12 @@ public class BaseX{ throw new InvalidInputException("Input must contain at least 1 letter"); } } - //Sets the numeric base + /** + * Sets the base for encoding and decoding, ensuring it is within valid range. + * + * @param base the base to be set + * @throws InvalidBaseException if the base is less than Character.MIN_RADIX or greater than Character.MAX_RADIX + */ protected void setBase(int base) throws InvalidBaseException{ if(base < Character.MIN_RADIX){ throw new InvalidBaseException("Base cannot be less than " + Character.MIN_RADIX); @@ -81,7 +128,9 @@ public class BaseX{ this.base = base; } - //Encode inputString, store it in outputString, and return it + /** + * Encodes the input string using the specified base. + */ protected void encode(){ logger.debug("Encoding"); @@ -102,7 +151,11 @@ public class BaseX{ outputString = output.toString().toUpperCase(); logger.debug("Saving output string '{}'", outputString); } - //Decode inputString, store it in outputString, and return it + /** + * Decodes the input string from the specified base. + * + * @throws InvalidCharacterException if the input string contains invalid characters for the base + */ protected void decode() throws InvalidCharacterException{ logger.debug("Decoding"); @@ -129,23 +182,49 @@ public class BaseX{ logger.debug("Saving output string '{}'", outputString); } - //Constructor + //?Constructor + /** + * Constructs a new {@code BaseX} instance with the default base of 2. + * + * @throws InvalidBaseException if the default base is invalid + */ public BaseX() throws InvalidBaseException{ reset(); setBase(2); } + /** + * Constructs a new {@code BaseX} instance with the specified base. + * + * @param base the base to be used for encoding and decoding + * @throws InvalidBaseException if the base is invalid + */ public BaseX(int base) throws InvalidBaseException{ reset(); setBase(base); } - //Sets the inputString and encodes the message + /** + * Encodes the given input string using the current base. + * + * @param inputString the string to be encoded + * @return the encoded string + * @throws InvalidInputException if the input string is invalid + */ public String encode(String inputString) throws InvalidInputException{ reset(); setInputStringEncode(inputString); encode(); return outputString; } + /** + * Encodes the given input string using the specified base. + * + * @param base the base to use for encoding + * @param inputString the string to be encoded + * @return the encoded string + * @throws InvalidBaseException if the base is invalid + * @throws InvalidInputException if the input string is invalid + */ public String encode(int base, String inputString) throws InvalidBaseException, InvalidInputException{ reset(); setBase(base); @@ -153,13 +232,30 @@ public class BaseX{ encode(); return outputString; } - //Sets the inputString and decodes the message + /** + * Decodes the given input string using the current base. + * + * @param inputString the string to be decoded + * @return the decoded string + * @throws InvalidCharacterException if the input string contains invalid characters + * @throws InvalidInputException if the input string is invalid + */ public String decode(String inputString) throws InvalidCharacterException, InvalidInputException{ reset(); setInputStringDecode(inputString); decode(); return outputString; } + /** + * Decodes the given input string using the specified base. + * + * @param base the base to use for decoding + * @param inputString the string to be decoded + * @return the decoded string + * @throws InvalidBaseException if the base is invalid + * @throws InvalidCharacterException if the input string contains invalid characters + * @throws InvalidInputException if the input string is invalid + */ public String decode(int base, String inputString) throws InvalidBaseException, InvalidCharacterException, InvalidInputException{ reset(); setBase(base); @@ -168,17 +264,34 @@ public class BaseX{ return outputString; } - //Getters + //?Getters + /** + * Gets the current input string. + * + * @return the input string + */ public String getInputString(){ return inputString; } + /** + * Gets the current output string. + * + * @return the output string + */ public String getOutputString(){ return outputString; } + /** + * Gets the current base. + * + * @return the base + */ public int getBase(){ return base; } - //Makes sure all variables are empty + /** + * Resets the input and output strings to empty. + */ public void reset(){ logger.debug("Resetting fields"); diff --git a/src/main/java/com/mattrixwv/cipherstream/monosubstitution/Beaufort.java b/src/main/java/com/mattrixwv/cipherstream/monosubstitution/Beaufort.java index bc17e15..44caa2d 100644 --- a/src/main/java/com/mattrixwv/cipherstream/monosubstitution/Beaufort.java +++ b/src/main/java/com/mattrixwv/cipherstream/monosubstitution/Beaufort.java @@ -1,7 +1,23 @@ //CipherStreamJava/src/main/java/com/mattrixwv/cipherstream/monosubstitution/Beaufort.java //Mattrixwv // Created: 02-23-22 -//Modified: 05-04-23 +//Modified: 08-11-24 +/* + Copyright (C) 2024 Mattrixwv + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ package com.mattrixwv.cipherstream.monosubstitution; @@ -12,23 +28,53 @@ import com.mattrixwv.cipherstream.exceptions.InvalidInputException; import com.mattrixwv.cipherstream.exceptions.InvalidKeywordException; +/** + * A class for encoding and decoding strings using the Beaufort cipher, + * which is a variant of the Vigenère cipher with additional steps. + * + *

+ * The Beaufort cipher consists of three main steps: + *

+ *
    + *
  • Atbash cipher for reversing the string
  • + *
  • Caesar cipher for shifting characters by a fixed amount
  • + *
  • Vigenère cipher for applying a keyword-based shift
  • + *
+ * This class allows you to encode and decode strings with options to preserve + * capitalization, whitespace, and symbols. + */ public class Beaufort{ private static final Logger logger = LoggerFactory.getLogger(Beaufort.class); - //Fields - protected String inputString; //This is the string that needs encoded/decoded - protected String outputString; //This is the string that is output after encoding/decoding - protected String keyword; //This is the keyword that is responsible for determining the offsets that you change each character by - //Settings - protected boolean preserveCapitals; //Persist capitals in the output string - protected boolean preserveWhitespace; //Persist whitespace in the output string - protected boolean preserveSymbols; //Persist symbols in the output string - //Internal ciphers - protected Atbash atbash; //The first step in encoding/decoding the cipher - protected Caesar caesar; //The second step in encoding/decoding the cipher - protected Vigenere vigenere; //The third step in encoding/decoding the cipher + //?Fields + /** This is the string that needs encoded/decoded */ + protected String inputString; + /** This is the string that is output after encoding/decoding */ + protected String outputString; + /** This is the keyword that is responsible for determining the offsets that you change each character by */ + protected String keyword; + //?Settings + /** Persist capitals in the output string */ + protected boolean preserveCapitals; + /** Persist whitespace in the output string */ + protected boolean preserveWhitespace; + /** Persist symbols in the output string */ + protected boolean preserveSymbols; + //?Internal ciphers + /** The first step in encoding/decoding the cipher */ + protected Atbash atbash; + /** The second step in encoding/decoding the cipher */ + protected Caesar caesar; + /** The third step in encoding/decoding the cipher */ + protected Vigenere vigenere; - //Ensures inputString constraints + /** + * Sets the input string for encoding or decoding, applying removal options + * for case, whitespace, and symbols. + * + * @param inputString the string to be processed + * @throws InvalidInputException if the input string is null or blank after processing + */ public void setInputString(String inputString) throws InvalidInputException{ //Make sure the input isn't null if(inputString == null){ @@ -63,7 +109,13 @@ public class Beaufort{ throw new InvalidInputException("Input must contain at least 1 letter"); } } - //Ensures keyword constraints + /** + * Sets the keyword for encoding or decoding, ensuring it contains only + * uppercase letters and is at least 2 letters long. + * + * @param keyword the keyword for the Vigenère cipher + * @throws InvalidKeywordException if the keyword is null, blank, or less than 2 letters + */ public void setKeyword(String keyword) throws InvalidKeywordException{ //Make sure the keyword isn't null if(keyword == null){ @@ -88,20 +140,38 @@ public class Beaufort{ throw new InvalidKeywordException("Keyword must contain at least 2 letters"); } } - //Encodes the inputString and stores the result in outputString + /** + * Encodes the input string using the Beaufort cipher and stores the result in {@code outputString}. + * + * @throws InvalidKeywordException if the keyword is invalid + * @throws InvalidInputException if the input string is invalid + */ protected void encode() throws InvalidKeywordException, InvalidInputException{ logger.debug("Encoding"); code(); } - //Decodes the inputString and stores the result in outputString + /** + * Decodes the input string using the Beaufort cipher and stores the result in {@code outputString}. + * Decoding is the same process as encoding in this cipher. + * + * @throws InvalidKeywordException if the keyword is invalid + * @throws InvalidInputException if the input string is invalid + */ protected void decode() throws InvalidKeywordException, InvalidInputException{ logger.debug("Decoding"); //Decoding is just encoding again code(); } - //Codes input and saves to output + /** + * Performs the Beaufort cipher encoding/decoding process: + *
    + *
  • Encodes the input string using the Atbash cipher
  • + *
  • Shifts the result by 1 using the Caesar cipher
  • + *
  • Applies the Vigenère cipher using the keyword
  • + *
+ */ protected void code(){ //Reverse the string logger.debug("Encoding with Atbash"); @@ -120,7 +190,10 @@ public class Beaufort{ } - //Constructor + //?Constructor + /** + * Constructs a new {@code Beaufort} instance with default settings. + */ public Beaufort(){ preserveCapitals = false; preserveWhitespace = false; @@ -130,6 +203,13 @@ public class Beaufort{ vigenere = new Vigenere(false, false, false); reset(); } + /** + * Constructs a new {@code Beaufort} instance with specified settings. + * + * @param preserveCapitals whether to preserve capitalization in the output + * @param preserveWhitespace whether to preserve whitespace in the output + * @param preserveSymbols whether to preserve symbols in the output + */ public Beaufort(boolean preserveCapitals, boolean preserveWhitespace, boolean preserveSymbols){ this.preserveCapitals = preserveCapitals; this.preserveWhitespace = preserveWhitespace; @@ -140,7 +220,15 @@ public class Beaufort{ reset(); } - //Encodes inputString using keyword and returns the result + /** + * Encodes the input string using the specified keyword. + * + * @param keyword the keyword for the Vigenère cipher + * @param inputString the string to be encoded + * @return the encoded string + * @throws InvalidKeywordException if the keyword is invalid + * @throws InvalidInputException if the input string is invalid + */ public String encode(String keyword, String inputString) throws InvalidKeywordException, InvalidInputException{ //Set the parameters setKeyword(keyword); @@ -150,7 +238,15 @@ public class Beaufort{ encode(); return outputString; } - //Decodes inputString using keyword and returns the result + /** + * Decodes the input string using the specified keyword. + * + * @param keyword the keyword for the Vigenère cipher + * @param inputString the string to be decoded + * @return the decoded string + * @throws InvalidKeywordException if the keyword is invalid + * @throws InvalidInputException if the input string is invalid + */ public String decode(String keyword, String inputString) throws InvalidKeywordException, InvalidInputException{ //Set the parameters setKeyword(keyword); @@ -161,17 +257,34 @@ public class Beaufort{ return outputString; } - //Getters + //?Getters + /** + * Gets the current input string. + * + * @return the input string + */ public String getInputString(){ return inputString; } + /** + * Gets the current output string. + * + * @return the output string + */ public String getOutputString(){ return outputString; } + /** + * Gets the current keyword. + * + * @return the keyword + */ public String getKeyword(){ return keyword; } - //Makes sure all variables are empty + /** + * Resets the input string, output string, and keyword to empty. + */ public void reset(){ logger.debug("Resetting fields"); diff --git a/src/main/java/com/mattrixwv/cipherstream/monosubstitution/Caesar.java b/src/main/java/com/mattrixwv/cipherstream/monosubstitution/Caesar.java index 1f62ab2..b6cabb2 100644 --- a/src/main/java/com/mattrixwv/cipherstream/monosubstitution/Caesar.java +++ b/src/main/java/com/mattrixwv/cipherstream/monosubstitution/Caesar.java @@ -1,7 +1,23 @@ //CipherStreamJava/src/main/java/com/mattrixwv/cipherstream/monosubstitution/Caesar.java //Matthew Ellison // Created: 07-25-21 -//Modified: 05-04-23 +//Modified: 08-11-24 +/* + Copyright (C) 2024 Mattrixwv + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ package com.mattrixwv.cipherstream.monosubstitution; @@ -11,19 +27,39 @@ import org.slf4j.LoggerFactory; import com.mattrixwv.cipherstream.exceptions.InvalidInputException; +/** + * A class for encoding and decoding strings using the Caesar cipher. + * + *

+ * The Caesar cipher is a substitution cipher where each letter in the + * plaintext is shifted a fixed number of places down or up the alphabet. + * This class allows you to encode and decode strings with options to preserve + * capitalization, whitespace, and symbols. + *

+ */ public class Caesar{ private static final Logger logger = LoggerFactory.getLogger(Caesar.class); - //Fields - protected String inputString; //The string that needs encoded/decoded - protected String outputString; //The encoded/decoded string - protected int shift; //The amount that you need to shift each letter - //Settings - protected boolean preserveCapitals; //Persist capitals in the output string - protected boolean preserveWhitespace; //Persist whitespace in the output string - protected boolean preserveSymbols; //Persist symbols in the output string + //?Fields + /** The string that needs encoded/decoded */ + protected String inputString; + /** The encoded/decoded string */ + protected String outputString; + /** The amount that you need to shift each letter */ + protected int shift; + //?Settings + /** Persist capitals in the output string */ + protected boolean preserveCapitals; + /** Persist whitespace in the output string */ + protected boolean preserveWhitespace; + /** Persist symbols in the output string */ + protected boolean preserveSymbols; - //Sets shift and makes sure it is within the propper bounds + /** + * Sets the shift amount and ensures it is within the proper bounds (0-25). + * + * @param shiftAmount the amount to shift each letter + */ protected void setShift(int shiftAmount){ logger.debug("Setting shift {}", shiftAmount); @@ -32,7 +68,13 @@ public class Caesar{ logger.debug("Cleaned shift {}", shift); } - //Sets the input string + /** + * Sets the input string for encoding or decoding, applying removal options + * for case, whitespace, and symbols. + * + * @param inputString the string to be processed + * @throws InvalidInputException if the input string is null or blank after processing + */ protected void setInputString(String inputString) throws InvalidInputException{ if(inputString == null){ throw new InvalidInputException("Input cannot be null"); @@ -63,7 +105,9 @@ public class Caesar{ throw new InvalidInputException("Input must contain at least 1 letter"); } } - //Encodes the inputString and stores the result in outputString + /** + * Encodes the input string by shifting letters according to the Caesar cipher. + */ protected void encode(){ logger.debug("Encoding"); @@ -111,7 +155,9 @@ public class Caesar{ outputString = output.toString(); logger.debug("Saving encoded string '{}'", outputString); } - //Decodes the inputString and stores the result in outputString + /** + * Decodes the input string by reversing the shift applied during encoding. + */ protected void decode(){ logger.debug("Decoding"); @@ -164,13 +210,23 @@ public class Caesar{ logger.debug("Saving decoded string '{}'", outputString); } - //Constructor + //?Constructor + /** + * Constructs a new {@code Caesar} instance with default settings. + */ public Caesar(){ reset(); preserveCapitals = false; preserveWhitespace = false; preserveSymbols = false; } + /** + * Constructs a new {@code Caesar} instance with specified settings. + * + * @param preserveCapitals whether to preserve capitalization in the output + * @param preserveWhitespace whether to preserve whitespace in the output + * @param preserveSymbols whether to preserve symbols in the output + */ public Caesar(boolean preserveCapitals, boolean preserveWhitespace, boolean preserveSymbols){ reset(); this.preserveCapitals = preserveCapitals; @@ -178,7 +234,14 @@ public class Caesar{ this.preserveSymbols = preserveSymbols; } - //Sets the shift and inputString and encodes the message + /** + * Encodes the input string with the specified shift amount. + * + * @param shiftAmount the amount to shift each letter + * @param inputString the string to be encoded + * @return the encoded string + * @throws InvalidInputException if the input string is invalid + */ public String encode(int shiftAmount, String inputString) throws InvalidInputException{ reset(); setShift(shiftAmount); @@ -186,7 +249,14 @@ public class Caesar{ encode(); return outputString; } - //Sets the shift and inputString and decodes the message + /** + * Decodes the input string with the specified shift amount. + * + * @param shiftAmount the amount to shift each letter + * @param inputString the string to be decoded + * @return the decoded string + * @throws InvalidInputException if the input string is invalid + */ public String decode(int shiftAmount, String inputString) throws InvalidInputException{ reset(); setShift(shiftAmount); @@ -195,17 +265,34 @@ public class Caesar{ return outputString; } - //Getters + //?Getters + /** + * Gets the current input string. + * + * @return the input string + */ public String getInputString(){ return inputString; } + /** + * Gets the current shift amount. + * + * @return the shift amount + */ public int getShift(){ return shift; } + /** + * Gets the current output string. + * + * @return the output string + */ public String getOutputString(){ return outputString; } - //Makes sure all variables are empty + /** + * Resets the internal fields to their default values. + */ public void reset(){ logger.debug("Resetting fields"); diff --git a/src/main/java/com/mattrixwv/cipherstream/monosubstitution/OneTimePad.java b/src/main/java/com/mattrixwv/cipherstream/monosubstitution/OneTimePad.java index a118977..0289789 100644 --- a/src/main/java/com/mattrixwv/cipherstream/monosubstitution/OneTimePad.java +++ b/src/main/java/com/mattrixwv/cipherstream/monosubstitution/OneTimePad.java @@ -1,7 +1,23 @@ //CipherStreamJava/src/main/java/com/mattrixwv/cipherstream/monosubstitution/OneTimePad.java //Mattrixwv // Created: 02-23-22 -//Modified: 05-04-23 +//Modified: 08-11-24 +/* + Copyright (C) 2024 Mattrixwv + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ package com.mattrixwv.cipherstream.monosubstitution; @@ -12,21 +28,51 @@ import com.mattrixwv.cipherstream.exceptions.InvalidInputException; import com.mattrixwv.cipherstream.exceptions.InvalidKeywordException; +/** + * A class for encoding and decoding strings using the One-Time Pad cipher, + * which is a special case of the Vigenère cipher where the key is as long as + * the input message and used only once. + * + *

+ * The One-Time Pad cipher provides perfect secrecy when the key is truly random, + * as long as the key length is equal to or greater than the length of the message + * and the key is used only once. + *

+ */ public class OneTimePad extends Vigenere{ private static final Logger logger = LoggerFactory.getLogger(OneTimePad.class); //?Add some kind of entropy calculator? - //Constructor + //?Constructor + /** + * Constructs a new {@code OneTimePad} instance with default settings. + */ public OneTimePad(){ super(); } + /** + * Constructs a new {@code OneTimePad} instance with specified settings. + * + * @param preserveCapitals whether to preserve capitalization in the output + * @param preserveWhitespace whether to preserve whitespace in the output + * @param preserveSymbols whether to preserve symbols in the output + */ public OneTimePad(boolean preserveCapitals, boolean preserveWhitespace, boolean preserveSymbols){ super(preserveCapitals, preserveWhitespace, preserveSymbols); } - //Encodes input using key and returns the result + /** + * Encodes the input string using the One-Time Pad cipher with the provided key. + * The key must be at least as long as the input string. + * + * @param keyword the key to use for encoding + * @param inputString the string to be encoded + * @return the encoded string + * @throws InvalidKeywordException if the key is shorter than the input string + * @throws InvalidInputException if the input string is invalid + */ @Override public String encode(String keyword, String inputString) throws InvalidKeywordException, InvalidInputException{ if(keyword.length() < inputString.length()){ @@ -37,7 +83,16 @@ public class OneTimePad extends Vigenere{ return super.encode(keyword, inputString); } - //Decodes input using key and returns the result + /** + * Decodes the input string using the One-Time Pad cipher with the provided key. + * The key must be at least as long as the input string. + * + * @param keyword the key to use for decoding + * @param inputString the string to be decoded + * @return the decoded string + * @throws InvalidKeywordException if the key is shorter than the input string + * @throws InvalidInputException if the input string is invalid + */ @Override public String decode(String keyword, String inputString) throws InvalidKeywordException, InvalidInputException{ if(keyword.length() < inputString.length()){ diff --git a/src/main/java/com/mattrixwv/cipherstream/monosubstitution/Porta.java b/src/main/java/com/mattrixwv/cipherstream/monosubstitution/Porta.java index 029192b..68e4437 100644 --- a/src/main/java/com/mattrixwv/cipherstream/monosubstitution/Porta.java +++ b/src/main/java/com/mattrixwv/cipherstream/monosubstitution/Porta.java @@ -1,7 +1,23 @@ //CipherStreamJava/src/main/java/com/mattrixwv/cipherstream/monosubstitution/Porta.java //Mattrixwv // Created: 02-28-22 -//Modified: 05-04-23 +//Modified: 08-11-24 +/* + Copyright (C) 2024 Mattrixwv + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ package com.mattrixwv.cipherstream.monosubstitution; @@ -12,9 +28,22 @@ import com.mattrixwv.cipherstream.exceptions.InvalidInputException; import com.mattrixwv.cipherstream.exceptions.InvalidKeywordException; +/** + * A class for encoding and decoding strings using the Porta cipher, + * which is a variant of the Vigenère cipher that uses a tableau of + * alphabets to encode and decode messages. + * + *

+ * The Porta cipher uses a series of Caesar ciphers based on a repeating + * keyword, with a pre-defined set of alphabetic shifts. This implementation + * allows for encoding and decoding of messages while preserving or removing + * certain characters based on configuration settings. + *

+ */ public class Porta{ private static final Logger logger = LoggerFactory.getLogger(Porta.class); + /** Predefined alphabetic tableau used for encoding and decoding */ private static final String[] tableau = { "NOPQRSTUVWXYZABCDEFGHIJKLM", //A-B "OPQRSTUVWXYZNMABCDEFGHIJKL", //C-D @@ -31,17 +60,28 @@ public class Porta{ "ZNOPQRSTUVWXYBCDEFGHIJKLMA" //Y-Z }; - //Fields - protected String inputString; //The string that needs encoded/decoded - protected String outputString; //The encoded/decoded string - protected String keyword; //The keyword used to encode the input string - //Settings - protected boolean preserveCapitals; //Persist capitals in the output string - protected boolean preserveWhitespace; //Persist whitespace in the output string - protected boolean preserveSymbols; //Persist symbols in the output string + //?Fields + /** The string that needs encoded/decoded */ + protected String inputString; + /** The encoded/decoded string */ + protected String outputString; + /** The keyword used to encode the input string */ + protected String keyword; + //?Settings + /** Persist capitals in the output string */ + protected boolean preserveCapitals; + /** Persist whitespace in the output string */ + protected boolean preserveWhitespace; + /** Persist symbols in the output string */ + protected boolean preserveSymbols; - //Ensure all keyword constraints are followed + /** + * Ensures all keyword constraints are followed. + * + * @param keyword the keyword to be used for encoding/decoding + * @throws InvalidKeywordException if the keyword is null, empty, or less than 2 characters + */ protected void setKeyword(String keyword) throws InvalidKeywordException{ //Make sure the keyword isn't null if(keyword == null){ @@ -67,7 +107,12 @@ public class Porta{ throw new InvalidKeywordException("Keyword must contain at least 2 letters"); } } - //Ensure all input constraints are followed + /** + * Ensures all input constraints are followed. + * + * @param inputString the string to be encoded/decoded + * @throws InvalidInputException if the input string is null or blank + */ protected void setInputString(String inputString) throws InvalidInputException{ //Ensure the input isn't null if(inputString == null){ @@ -102,7 +147,13 @@ public class Porta{ throw new InvalidInputException("Input must contain at least 1 letter"); } } - //Returns the letter that replaces the passed in letter + /** + * Returns the letter that replaces the passed-in letter based on the keyword and tableau. + * + * @param keywordCnt the index of the keyword character to use + * @param letter the letter to be replaced + * @return the replacement letter + */ protected char getReplacer(int keywordCnt, char letter){ logger.debug("Getting letter that replaces {} at {}", letter, keywordCnt); @@ -130,21 +181,30 @@ public class Porta{ logger.debug("Replacer {}", replacer); return replacer; } - //Encodes the inputString and stores the result in outputString + /** + * Encodes the inputString and stores the result in outputString. + * Encoding is the same as decoding for this cipher. + */ protected void encode(){ logger.debug("Encoding"); //Encoding is the same as decoding code(); } - //Decodes the inputString and stores the result in outputString + /** + * Decodes the inputString and stores the result in outputString. + * Decoding is the same as encoding for this cipher. + */ protected void decode(){ logger.debug("Decoding"); //Decoding is the same as encoding code(); } - //Codes the inputString and stores the result in outputString + /** + * Encodes or decodes the inputString based on the provided keyword. + * Uses the tableau to replace characters. + */ protected void code(){ StringBuilder output = new StringBuilder(); @@ -175,13 +235,23 @@ public class Porta{ } - //Constructor + //?Constructor + /** + * Constructs a new {@code Porta} instance with default settings. + */ public Porta(){ preserveCapitals = false; preserveWhitespace = false; preserveSymbols = false; reset(); } + /** + * Constructs a new {@code Porta} instance with specified settings. + * + * @param preserveCapitals whether to preserve capitalization in the output + * @param preserveWhitespace whether to preserve whitespace in the output + * @param preserveSymbols whether to preserve symbols in the output + */ public Porta(boolean preserveCapitals, boolean preserveWhitespace, boolean preserveSymbols){ this.preserveCapitals = preserveCapitals; this.preserveWhitespace = preserveWhitespace; @@ -189,7 +259,15 @@ public class Porta{ reset(); } - //Sets the keyword and inputString and encodes the message + /** + * Sets the keyword and inputString and encodes the message. + * + * @param keyword the keyword to use for encoding + * @param inputString the string to be encoded + * @return the encoded string + * @throws InvalidKeywordException if the keyword is invalid + * @throws InvalidInputException if the input string is invalid + */ public String encode(String keyword, String inputString) throws InvalidKeywordException, InvalidInputException{ //Set the parameters reset(); @@ -200,7 +278,15 @@ public class Porta{ encode(); return outputString; } - //Sets the keyword and inputString and decodes the message + /** + * Sets the keyword and inputString and decodes the message. + * + * @param keyword the keyword to use for decoding + * @param inputString the string to be decoded + * @return the decoded string + * @throws InvalidKeywordException if the keyword is invalid + * @throws InvalidInputException if the input string is invalid + */ public String decode(String keyword, String inputString) throws InvalidKeywordException, InvalidInputException{ //Set the parameters reset(); @@ -212,17 +298,34 @@ public class Porta{ return outputString; } - //Getters + //?Getters + /** + * Gets the current input string. + * + * @return the input string + */ public String getInputString(){ return inputString; } + /** + * Gets the current output string. + * + * @return the output string + */ public String getOutputString(){ return outputString; } + /** + * Gets the current keyword. + * + * @return the keyword + */ public String getKeyword(){ return keyword; } - //Makes sure all fields are empty + /** + * Resets all fields to their default values. + */ public void reset(){ logger.debug("Resetting fields"); diff --git a/src/main/java/com/mattrixwv/cipherstream/monosubstitution/Substitution.java b/src/main/java/com/mattrixwv/cipherstream/monosubstitution/Substitution.java index 10ed91b..9f520d2 100644 --- a/src/main/java/com/mattrixwv/cipherstream/monosubstitution/Substitution.java +++ b/src/main/java/com/mattrixwv/cipherstream/monosubstitution/Substitution.java @@ -1,7 +1,23 @@ //CipherStreamJava/src/main/java/com/mattrixwv/cipherstream/monosubstitution/Substitution.java //Mattrixwv // Created: 02-22-22 -//Modified: 05-04-23 +//Modified: 08-11-24 +/* + Copyright (C) 2024 Mattrixwv + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ package com.mattrixwv.cipherstream.monosubstitution; @@ -12,19 +28,41 @@ import com.mattrixwv.cipherstream.exceptions.InvalidInputException; import com.mattrixwv.cipherstream.exceptions.InvalidKeywordException; +/** + * A class for encoding and decoding strings using a substitution cipher. + * This cipher can handle both alphabetic and alphanumeric keys and supports + * preserving or removing capitalization, whitespace, and symbols. + * + *

+ * The substitution cipher replaces each letter or digit in the input string + * with a corresponding character from a key. The key must contain all letters + * of the alphabet and optionally digits, without duplicates. + *

+ */ public class Substitution{ private static final Logger logger = LoggerFactory.getLogger(Substitution.class); - //Fields - protected String inputString; //The string that needs encoded/decoded - protected String outputString; //The encoded/decoded string - protected String keyword; //The keyword used to encode/decode the input - //Getters - protected boolean preserveCapitals; //Persist capitals in the output string - protected boolean preserveWhitespace; //Persist whitespace in the output string - protected boolean preserveSymbols; //Persist symbols in the output string + //?Fields + /** The string that needs encoded/decoded */ + protected String inputString; + /** The encoded/decoded string */ + protected String outputString; + /** The keyword used to encode/decode the input */ + protected String keyword; + //?Getters + /** Persist capitals in the output string */ + protected boolean preserveCapitals; + /** Persist whitespace in the output string */ + protected boolean preserveWhitespace; + /** Persist symbols in the output string */ + protected boolean preserveSymbols; - //Ensures key constraints are followed + /** + * Ensures all key constraints are followed. + * + * @param key the key to be used for encoding/decoding + * @throws InvalidKeywordException if the key is null, contains duplicates, or has invalid length + */ protected void setKeyword(String key) throws InvalidKeywordException{ if(key == null){ throw new InvalidKeywordException("Key cannot be null"); @@ -71,7 +109,12 @@ public class Substitution{ logger.debug("Cleaned key '{}'", key); this.keyword = key; } - //Ensure intput constraints are followed + /** + * Ensures all input constraints are followed. + * + * @param inputString the string to be encoded/decoded + * @throws InvalidInputException if the input string is null or blank + */ protected void setInputString(String inputString) throws InvalidInputException{ if(inputString == null){ throw new InvalidInputException("Input cannot be null"); @@ -105,7 +148,9 @@ public class Substitution{ throw new InvalidInputException("Input must contain at least 1 letter"); } } - //Encodes the inputString and stores the result in outputString + /** + * Encodes the inputString using the provided key and stores the result in outputString. + */ protected void encode(){ logger.debug("Encoding"); @@ -137,7 +182,9 @@ public class Substitution{ this.outputString = output.toString(); logger.debug("Encoded message '{}'", outputString); } - //Decodes the inputString and stores the result in outputString + /** + * Decodes the inputString using the provided key and stores the result in outputString. + */ protected void decode(){ logger.debug("Decoding"); @@ -173,13 +220,23 @@ public class Substitution{ logger.debug("Decoded message '{}'", outputString); } - //Constructors + //?Constructors + /** + * Constructs a new {@code Substitution} instance with default settings. + */ public Substitution(){ preserveCapitals = false; preserveWhitespace = false; preserveSymbols = false; reset(); } + /** + * Constructs a new {@code Substitution} instance with specified settings. + * + * @param preserveCapitals whether to preserve capitalization in the output + * @param preserveWhitespace whether to preserve whitespace in the output + * @param preserveSymbols whether to preserve symbols in the output + */ public Substitution(boolean preserveCapitals, boolean preserveWhitespace, boolean preserveSymbols){ this.preserveCapitals = preserveCapitals; this.preserveWhitespace = preserveWhitespace; @@ -187,14 +244,30 @@ public class Substitution{ reset(); } - //Encodes inputString using the provided key + /** + * Encodes the inputString using the provided key. + * + * @param key the key to use for encoding + * @param inputString the string to be encoded + * @return the encoded string + * @throws InvalidKeywordException if the key is invalid + * @throws InvalidInputException if the input string is invalid + */ public String encode(String key, String inputString) throws InvalidKeywordException, InvalidInputException{ setKeyword(key); setInputString(inputString); encode(); return outputString; } - //Decodes inputString using the provided key + /** + * Decodes the inputString using the provided key. + * + * @param key the key to use for decoding + * @param inputString the string to be decoded + * @return the decoded string + * @throws InvalidKeywordException if the key is invalid + * @throws InvalidInputException if the input string is invalid + */ public String decode(String key, String inputString) throws InvalidKeywordException, InvalidInputException{ setKeyword(key); setInputString(inputString); @@ -202,17 +275,34 @@ public class Substitution{ return outputString; } - //Getters + //?Getters + /** + * Gets the current input string. + * + * @return the input string + */ public String getInputString(){ return inputString; } + /** + * Gets the current output string. + * + * @return the output string + */ public String getOutputString(){ return outputString; } + /** + * Gets the current keyword. + * + * @return the keyword + */ public String getKeyword(){ return keyword; } - //Makes sure all variables are empty + /** + * Resets all fields to their default values. + */ public void reset(){ logger.debug("Resetting fields"); diff --git a/src/main/java/com/mattrixwv/cipherstream/monosubstitution/Vigenere.java b/src/main/java/com/mattrixwv/cipherstream/monosubstitution/Vigenere.java index e8a5a98..4aee140 100644 --- a/src/main/java/com/mattrixwv/cipherstream/monosubstitution/Vigenere.java +++ b/src/main/java/com/mattrixwv/cipherstream/monosubstitution/Vigenere.java @@ -1,7 +1,23 @@ //CipherStreamJava/src/main/java/com/mattrixwv/cipherstream/monosubstitution/Vigenere.java //Matthew Ellison // Created: 07-25-21 -//Modified: 05-04-23 +//Modified: 08-11-24 +/* + Copyright (C) 2024 Mattrixwv + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ package com.mattrixwv.cipherstream.monosubstitution; @@ -15,20 +31,38 @@ import com.mattrixwv.cipherstream.exceptions.InvalidInputException; import com.mattrixwv.cipherstream.exceptions.InvalidKeywordException; +/** + * A class for encoding and decoding strings using the Vigenère cipher. + * This cipher uses a keyword to determine the shift for each character in the input string. + * + *

+ * The Vigenère cipher applies a series of Caesar ciphers based on the letters of a keyword. + * The keyword determines the shift for each letter in the input string. + *

+ */ public class Vigenere{ private static final Logger logger = LoggerFactory.getLogger(Vigenere.class); //Fields - protected String inputString; //This is the string that needs encoded/decoded - protected String outputString; //This is the string that is output after encoding/decoding - protected String keyword; //This is the keyword that is resposible for determining the offsets that you change each character by - protected ArrayList offset; //Holds the offsets coputed from each character in the keyword + /** This is the string that needs encoded/decoded */ + protected String inputString; + /** This is the string that is output after encoding/decoding */ + protected String outputString; + /** This is the keyword that is resposible for determining the offsets that you change each character by */ + protected String keyword; + /** Holds the offsets coputed from each character in the keyword */ + protected ArrayList offset; //Settings - protected boolean preserveCapitals; //Persist capitals in the output string - protected boolean preserveWhitespace; //Persist whitespace in the output string - protected boolean preserveSymbols; //Persist symbols in the output string + /** Persist capitals in the output string */ + protected boolean preserveCapitals; + /** Persist whitespace in the output string */ + protected boolean preserveWhitespace; + /** Persist symbols in the output string */ + protected boolean preserveSymbols; - //Uses keyword to calculate the offset for the Caesar cipher for each character + /** + * Calculates the offsets for the Vigenère cipher from the keyword. + */ protected void setOffset(){ logger.debug("Setting offset array from keyword"); @@ -43,7 +77,12 @@ public class Vigenere{ logger.debug("Offset {}", offset); } - //Sets inputString + /** + * Sets the input string and applies transformation settings. + * + * @param inputString the string to be encoded/decoded + * @throws InvalidInputException if the input string is null or blank + */ protected void setInputString(String inputString) throws InvalidInputException{ if(inputString == null){ throw new InvalidInputException("Input cannot be null"); @@ -74,7 +113,12 @@ public class Vigenere{ throw new InvalidInputException("Input must contain at least 1 letter"); } } - //Sets keyword + /** + * Sets the keyword for the Vigenère cipher and computes the offsets. + * + * @param keyword the keyword to be used for encoding/decoding + * @throws InvalidKeywordException if the keyword is null, too short, or contains invalid characters + */ protected void setKeyword(String keyword) throws InvalidKeywordException{ if(keyword == null){ throw new InvalidKeywordException("Keyword cannot be null"); @@ -102,7 +146,9 @@ public class Vigenere{ throw new InvalidKeywordException("Keyword must contain at least 2 letters"); } } - //Encodes inputString and stores the result in outputString + /** + * Encodes the input string using the Vigenère cipher and stores the result. + */ protected void encode(){ logger.debug("Encoding"); @@ -147,7 +193,9 @@ public class Vigenere{ outputString = output.toString(); logger.debug("Encoded message '{}'", outputString); } - //Decodes inputString and stores the result in outputString + /** + * Decodes the input string using the Vigenère cipher and stores the result. + */ protected void decode(){ logger.debug("Decoding"); @@ -194,7 +242,10 @@ public class Vigenere{ } - //Constructor + //?Constructor + /** + * Constructs a new {@code Vigenere} instance with default settings. + */ public Vigenere(){ offset = new ArrayList<>(); reset(); @@ -202,6 +253,13 @@ public class Vigenere{ preserveWhitespace = false; preserveSymbols = false; } + /** + * Constructs a new {@code Vigenere} instance with specified settings. + * + * @param preserveCapitals whether to preserve capitalization in the output + * @param preserveWhitespace whether to preserve whitespace in the output + * @param preserveSymbols whether to preserve symbols in the output + */ public Vigenere(boolean preserveCapitals, boolean preserveWhitespace, boolean preserveSymbols){ offset = new ArrayList<>(); reset(); @@ -210,7 +268,15 @@ public class Vigenere{ this.preserveSymbols = preserveSymbols; } - //Encodes input using key and returns the result + /** + * Encodes the input string using the provided keyword. + * + * @param keyword the keyword to use for encoding + * @param inputString the string to be encoded + * @return the encoded string + * @throws InvalidKeywordException if the keyword is invalid + * @throws InvalidInputException if the input string is invalid + */ public String encode(String keyword, String inputString) throws InvalidKeywordException, InvalidInputException{ reset(); setKeyword(keyword); @@ -218,7 +284,15 @@ public class Vigenere{ encode(); return outputString; } - //Decodes input using key and returns the result + /** + * Decodes the input string using the provided keyword. + * + * @param keyword the keyword to use for decoding + * @param inputString the string to be decoded + * @return the decoded string + * @throws InvalidKeywordException if the keyword is invalid + * @throws InvalidInputException if the input string is invalid + */ public String decode(String keyword, String inputString) throws InvalidKeywordException, InvalidInputException{ reset(); setKeyword(keyword); @@ -227,21 +301,42 @@ public class Vigenere{ return outputString; } - //Getters + //?Getters + /** + * Gets the current input string. + * + * @return the input string + */ public String getInputString(){ return inputString; } + /** + * Gets the current output string. + * + * @return the output string + */ public String getOutputString(){ return outputString; } + /** + * Gets the current keyword. + * + * @return the keyword + */ public String getKeyword(){ return keyword; } + /** + * Gets the current offset list. + * + * @return the offset list + */ public List getOffsets(){ return offset; } - - //Makes sure all variables are empty + /** + * Resets all fields to their default values. + */ public void reset(){ logger.debug("Resetting fields"); diff --git a/src/main/java/com/mattrixwv/cipherstream/polysubstitution/Bifid.java b/src/main/java/com/mattrixwv/cipherstream/polysubstitution/Bifid.java index 6c9d522..94fe932 100644 --- a/src/main/java/com/mattrixwv/cipherstream/polysubstitution/Bifid.java +++ b/src/main/java/com/mattrixwv/cipherstream/polysubstitution/Bifid.java @@ -1,7 +1,23 @@ //CipherStreamJava/src/main/java/com/mattrixwv/cipherstream/polysubstitution/Bifid.java //Mattrixwv // Created: 03-03-22 -//Modified: 05-04-23 +//Modified: 08-11-24 +/* + Copyright (C) 2024 Mattrixwv + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ package com.mattrixwv.cipherstream.polysubstitution; @@ -13,21 +29,44 @@ import com.mattrixwv.cipherstream.exceptions.InvalidInputException; import com.mattrixwv.cipherstream.exceptions.InvalidKeywordException; +/** + * A class for encoding and decoding strings using the Bifid cipher. + * The Bifid cipher is a polygraphic substitution cipher that uses a Polybius square + * and applies a columnar transposition to encode or decode messages. + * + *

+ * The Bifid cipher operates by converting the plaintext message into coordinates based on a + * Polybius square, then rearranges these coordinates using a transposition before converting + * them back into text. + *

+ */ public class Bifid{ private static final Logger logger = LoggerFactory.getLogger(Bifid.class); - //Fields - protected String inputString; //The message that needs to be encoded/decoded - protected String outputString; //The encoded/decoded message - protected String keyword; //The keyword used to create the grid - //Settings - protected boolean preserveCapitals; //Persist capitals in the output string - protected boolean preserveWhitespace; //Persist whitespace in the output string - protected boolean preserveSymbols; //Persist symbols in the output string - //Internal ciphers - protected PolybiusSquare polybiusSquare; //Used to encode the message to numbers then back into letters + //?Fields + /** The message that needs to be encoded/decoded */ + protected String inputString; + /** The encoded/decoded message */ + protected String outputString; + /** The keyword used to create the grid */ + protected String keyword; + //?Settings + /** Persist capitals in the output string */ + protected boolean preserveCapitals; + /** Persist whitespace in the output string */ + protected boolean preserveWhitespace; + /** Persist symbols in the output string */ + protected boolean preserveSymbols; + //?Internal ciphers + /** Used to encode the message to numbers then back into letters */ + protected PolybiusSquare polybiusSquare; - //Strips invalid characters from the keyword and creates the grid + /** + * Sets the keyword for creating the Polybius square. + * + * @param keyword the keyword to use for the Polybius square + * @throws InvalidKeywordException if the keyword is null + */ protected void setKeyword(String keyword) throws InvalidKeywordException{ //Ensure the keyword isn't null if(keyword == null){ @@ -39,7 +78,12 @@ public class Bifid{ //Save the key for polybius to deal with this.keyword = keyword; } - //Ensures inputString constraints + /** + * Validates and preprocesses the input string based on the current settings. + * + * @param inputString the string to be encoded/decoded + * @throws InvalidInputException if the input string is null or blank + */ protected void setInputString(String inputString) throws InvalidInputException{ //Ensure the input string isn't null if(inputString == null){ @@ -74,7 +118,11 @@ public class Bifid{ throw new InvalidInputException("Input must contain at least 1 letter"); } } - //Adds all non-letter characters back to the output string + /** + * Formats the encoded/decoded output to match the input string's original format. + * + * @param outputString the encoded/decoded message to be formatted + */ protected void formatOutput(String outputString){ logger.debug("Formatting output"); //Keep track of where you are in the output @@ -104,7 +152,12 @@ public class Bifid{ this.outputString = output.toString(); logger.debug("Formatted output string '{}'", this.outputString); } - //Encodes inputString using a polybius square and stores the result in outputString + /** + * Encodes the input string using the Bifid cipher and stores the result in outputString. + * + * @throws InvalidCharacterException if there are invalid characters in the input + * @throws InvalidInputException if the input string is invalid + */ protected void encode() throws InvalidCharacterException, InvalidInputException{ logger.debug("Encoding"); @@ -140,7 +193,12 @@ public class Bifid{ //Format the output formatOutput(letterResult); } - //Decodes inputString using a polybius square and stores the result in outputString + /** + * Decodes the input string using the Bifid cipher and stores the result in outputString. + * + * @throws InvalidCharacterException if there are invalid characters in the input + * @throws InvalidInputException if the input string is invalid + */ protected void decode() throws InvalidCharacterException, InvalidInputException{ logger.debug("Decoding"); @@ -170,7 +228,12 @@ public class Bifid{ } - //Constructors + //?Constructors + /** + * Constructs a new {@code Bifid} instance with default settings. + * + * @throws InvalidCharacterException if initialization of PolybiusSquare fails + */ public Bifid() throws InvalidCharacterException{ preserveCapitals = false; preserveWhitespace = false; @@ -178,6 +241,14 @@ public class Bifid{ polybiusSquare = new PolybiusSquare(false, false); reset(); } + /** + * Constructs a new {@code Bifid} instance with specified settings. + * + * @param preserveCapitals whether to preserve capitalization in the output + * @param preserveWhitespace whether to preserve whitespace in the output + * @param preserveSymbols whether to preserve symbols in the output + * @throws InvalidCharacterException if initialization of PolybiusSquare fails + */ public Bifid(boolean preserveCapitals, boolean preserveWhitespace, boolean preserveSymbols) throws InvalidCharacterException{ this.preserveCapitals = preserveCapitals; this.preserveWhitespace = preserveWhitespace; @@ -186,7 +257,16 @@ public class Bifid{ reset(); } - //Encodes inputString using keyword and returns the result + /** + * Encodes the input string using the provided keyword. + * + * @param keyword the keyword to use for encoding + * @param inputString the string to be encoded + * @return the encoded string + * @throws InvalidKeywordException if the keyword is invalid + * @throws InvalidInputException if the input string is invalid + * @throws InvalidCharacterException if the input contains invalid characters + */ public String encode(String keyword, String inputString) throws InvalidKeywordException, InvalidInputException, InvalidCharacterException{ //Set the parameters reset(); @@ -197,7 +277,16 @@ public class Bifid{ encode(); return outputString; } - //Decodes inputString using keyword and returns the result + /** + * Decodes the input string using the provided keyword. + * + * @param keyword the keyword to use for decoding + * @param inputString the string to be decoded + * @return the decoded string + * @throws InvalidKeywordException if the keyword is invalid + * @throws InvalidInputException if the input string is invalid + * @throws InvalidCharacterException if the input contains invalid characters + */ public String decode(String keyword, String inputString) throws InvalidKeywordException, InvalidInputException, InvalidCharacterException{ //Set the parameters reset(); @@ -209,18 +298,34 @@ public class Bifid{ return outputString; } - //Getters + //?Getters + /** + * Gets the current input string. + * + * @return the input string + */ public String getInputString(){ return inputString; } + /** + * Gets the current output string. + * + * @return the output string + */ public String getOutputString(){ return outputString; } + /** + * Gets the current keyword. + * + * @return the keyword + */ public String getKeyword(){ return keyword; } - - //Makes sure all variables are empty + /** + * Resets all fields to their default values. + */ public void reset(){ logger.debug("Resetting fields"); diff --git a/src/main/java/com/mattrixwv/cipherstream/polysubstitution/Columnar.java b/src/main/java/com/mattrixwv/cipherstream/polysubstitution/Columnar.java index 10431bd..a65795a 100644 --- a/src/main/java/com/mattrixwv/cipherstream/polysubstitution/Columnar.java +++ b/src/main/java/com/mattrixwv/cipherstream/polysubstitution/Columnar.java @@ -1,7 +1,23 @@ //MattrixwvWebsite/src/main/java/com/mattrixwv/cipherstream/polysubstitution/Columnar.java //Mattrixwv // Created: 01-16-22 -//Modified: 05-04-23 +//Modified: 08-11-24 +/* + Copyright (C) 2024 Mattrixwv + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ package com.mattrixwv.cipherstream.polysubstitution; @@ -17,28 +33,54 @@ import com.mattrixwv.cipherstream.exceptions.InvalidInputException; import com.mattrixwv.cipherstream.exceptions.InvalidKeywordException; +/** + * This class implements the Columnar Transposition cipher for encoding and decoding messages. + * The Columnar Transposition cipher rearranges the letters of the plaintext based on a keyword, + * and then reads the message column-wise to produce the encoded output. For decoding, it reverses + * this process. + *

+ * This class provides methods to configure the cipher, process input strings, and generate output. + * It also includes options to preserve capitalization, whitespace, symbols, and to handle padding characters. + *

+ */ public class Columnar{ private static final Logger logger = LoggerFactory.getLogger(Columnar.class); - //Fields - protected String inputString; //The message that needs to be encoded/decoded - protected String outputString; //The encoded/decoded message - protected String keyword; //The keyword used to create the grid - protected char characterToAdd; //The character that is added to the end of a string to bring it to the correct length - protected int charsAdded; //The number of characters that were added to the end of the message - protected ArrayList> grid; //The grid used to encode/decode the message - //Settings - protected boolean preserveCapitals; //Persist capitals in the output string - protected boolean preserveWhitespace; //Persist whitespace in the output string - protected boolean preserveSymbols; //Persist symbols in the output string - protected boolean removePadding; //Remove the padding letters added to the cipher + //?Fields + /** The message that needs to be encoded/decoded */ + protected String inputString; + /** The encoded/decoded message */ + protected String outputString; + /** The keyword used to create the grid */ + protected String keyword; + /** The character that is added to the end of a string to bring it to the correct length */ + protected char characterToAdd; + /** The number of characters that were added to the end of the message */ + protected int charsAdded; + /** The grid used to encode/decode the message */ + protected ArrayList> grid; + //?Settings + /** Persist capitals in the output string */ + protected boolean preserveCapitals; + /** Persist whitespace in the output string */ + protected boolean preserveWhitespace; + /** Persist symbols in the output string */ + protected boolean preserveSymbols; + /** Remove the padding letters added to the cipher */ + protected boolean removePadding; - //Strip the inputString of all non-letter characters and change them to capitals + /** + * Strip the inputString of all non-letter characters and change them to capitals + * + * @return The input string in capital letters with all non-letter characters removed + */ protected String getCleanInputString(){ logger.debug("Cleaning input string"); return inputString.toUpperCase().replaceAll("[^A-Z]", ""); } - //Create the grid from the keyword + /** + * Creates the grid used for encoding. + */ protected void createGridEncode(){ logger.debug("Creating grid for encoding"); @@ -58,6 +100,9 @@ public class Columnar{ ))); } } + /** + * Creates the grid used for decoding. + */ protected void createGridDecode(){ logger.debug("Creating grid for decoding"); @@ -86,7 +131,12 @@ public class Columnar{ } } } - //Strips invalid characters from the string that needs encoded/decoded + /** + * Sets the input string for encoding, applying necessary modifications and padding. + * + * @param inputString the input string to encode + * @throws InvalidInputException if the input string is null or blank + */ protected void setInputStringEncode(String inputString) throws InvalidInputException{ logger.debug("Setting input string for encoding"); @@ -140,6 +190,12 @@ public class Columnar{ throw new InvalidInputException("Input cannot be blank"); } } + /** + * Sets the input string for decoding, applying necessary adjustments and padding. + * + * @param inputString the input string to decode + * @throws InvalidInputException if the input string is null or blank + */ protected void setInputStringDecode(String inputString) throws InvalidInputException{ logger.debug("Setting input string for decoding"); @@ -225,7 +281,9 @@ public class Columnar{ throw new InvalidInputException("Input cannot be blank"); } } - //Creates the output string from the grid + /** + * Creates the output string by reading the columns of the grid. + */ protected void createOutputStringFromColumns(){ logger.debug("Creating output string for encoding"); @@ -275,6 +333,9 @@ public class Columnar{ outputString = output.toString(); logger.debug("Output string '{}'", outputString); } + /** + * Creates the output string by reading the rows of the grid. + */ protected void createOutputStringFromRows(){ logger.debug("Creating output string for decoding"); @@ -345,7 +406,12 @@ public class Columnar{ outputString = output.toString(); logger.debug("Decoded output string '{}'", outputString); } - //Strips invalid characters from the keyword and creates the grid + /** + * Sets the keyword used for encoding or decoding. + * + * @param keyword the keyword to use + * @throws InvalidKeywordException if the keyword is null, contains less than 2 letters, or contains invalid characters + */ protected void setKeyword(String keyword) throws InvalidKeywordException{ //Ensure the keyword isn't null if(keyword == null){ @@ -365,7 +431,12 @@ public class Columnar{ throw new InvalidKeywordException("The keyword must contain at least 2 letters"); } } - //Set the character that is added to the end of the string + /** + * Sets the character used for padding. + * + * @param characterToAdd the padding character + * @throws InvalidCharacterException if the padding character is not a letter + */ protected void setCharacterToAdd(char characterToAdd) throws InvalidCharacterException{ if(!Character.isAlphabetic(characterToAdd)){ throw new InvalidCharacterException("Character to add must be a letter"); @@ -381,7 +452,11 @@ public class Columnar{ logger.debug("Character to add for padding {}", characterToAdd); } - //Returns a list of integers that represents the location of the characters of the keyword in alphabetic order + /** + * Gets the positions of the keyword characters in alphabetical order. + * + * @return the list of positions of keyword characters in alphabetical order + */ protected ArrayList getKeywordAlphaLocations(){ logger.debug("Creating an array of keyword letter locations"); @@ -400,6 +475,11 @@ public class Columnar{ logger.debug("Array of keyword letters {}", orderedLocations); return orderedLocations; } + /** + * Gets the original positions of the keyword characters. + * + * @return the list of original positions of keyword characters + */ protected ArrayList getKeywordOriginalLocations(){ logger.debug("Creating array of original keyword locations"); @@ -420,7 +500,11 @@ public class Columnar{ logger.debug("Array of keyword letters {}", originalOrder); return originalOrder; } - //Rearanges the grid based on the list of numbers given + /** + * Rearranges the grid based on the specified order. + * + * @param listOrder the order in which columns should be rearranged + */ protected void rearangeGrid(ArrayList listOrder){ logger.debug("Rearanging grid"); @@ -442,7 +526,9 @@ public class Columnar{ logger.debug("New grid {}", newGrid); grid = newGrid; } - //Encodes inputString using the Columnar cipher and stores the result in outputString + /** + * Encodes the input string using the Columnar cipher. + */ protected void encode(){ logger.debug("Encoding"); @@ -455,7 +541,9 @@ public class Columnar{ //Create the output createOutputStringFromColumns(); } - //Decodes inputString using the Columnar cipher and stores the result in outputString + /** + * Decodes the input string using the Columnar cipher. + */ protected void decode(){ logger.debug("Decoding"); @@ -468,7 +556,13 @@ public class Columnar{ createOutputStringFromRows(); } - //Constructors + //?Constructors + /** + * Constructs a new Columnar cipher instance with default settings. + * The default settings include preserving no capitalization, whitespace, or symbols, and using 'x' as the padding character. + * + * @throws InvalidCharacterException if the default padding character is invalid + */ public Columnar() throws InvalidCharacterException{ preserveCapitals = false; preserveWhitespace = false; @@ -477,6 +571,15 @@ public class Columnar{ setCharacterToAdd('x'); reset(); } + /** + * Constructs a new Columnar cipher instance with customizable settings. + * + * @param preserveCapitals whether to preserve capitalization in the output + * @param preserveWhitespace whether to preserve whitespace in the output + * @param preserveSymbols whether to preserve symbols in the output + * @param removePadding whether to remove padding characters from the output + * @throws InvalidCharacterException if the default padding character is invalid + */ public Columnar(boolean preserveCapitals, boolean preserveWhitespace, boolean preserveSymbols, boolean removePadding) throws InvalidCharacterException{ this.preserveCapitals = preserveCapitals; this.preserveWhitespace = preserveWhitespace; @@ -485,6 +588,16 @@ public class Columnar{ setCharacterToAdd('x'); reset(); } + /** + * Constructs a new Columnar cipher instance with customizable settings and a specific padding character. + * + * @param preserveCapitals whether to preserve capitalization in the output + * @param preserveWhitespace whether to preserve whitespace in the output + * @param preserveSymbols whether to preserve symbols in the output + * @param removePadding whether to remove padding characters from the output + * @param characterToAdd the character to use for padding + * @throws InvalidCharacterException if the padding character is not a letter + */ public Columnar(boolean preserveCapitals, boolean preserveWhitespace, boolean preserveSymbols, boolean removePadding, char characterToAdd) throws InvalidCharacterException{ this.preserveCapitals = preserveCapitals; this.preserveWhitespace = preserveWhitespace; @@ -494,7 +607,15 @@ public class Columnar{ reset(); } - //Encodes inputString using keyword and returns the result + /** + * Encodes the given input string using the provided keyword. + * + * @param keyword the keyword used for encoding + * @param inputString the message to encode + * @return the encoded message + * @throws InvalidKeywordException if the keyword is invalid + * @throws InvalidInputException if the input string is invalid + */ public String encode(String keyword, String inputString) throws InvalidKeywordException, InvalidInputException{ //Set the parameters reset(); @@ -505,7 +626,15 @@ public class Columnar{ encode(); return outputString; } - //Encodes inputString using keyword and returns the result + /** + * Decodes the given input string using the provided keyword. + * + * @param keyword the keyword used for decoding + * @param inputString the message to decode + * @return the decoded message + * @throws InvalidKeywordException if the keyword is invalid + * @throws InvalidInputException if the input string is invalid + */ public String decode(String keyword, String inputString) throws InvalidKeywordException, InvalidInputException{ //Set the parameters reset(); @@ -517,7 +646,9 @@ public class Columnar{ return outputString; } - //Makes sure all variables are empty + /** + * Resets all fields to their default values. + */ public void reset(){ logger.debug("Resetting fields"); @@ -528,13 +659,28 @@ public class Columnar{ charsAdded = 0; } - //Getters + //?Getters + /** + * Gets the current input string. + * + * @return the input string + */ public String getInputString(){ return inputString; } + /** + * Gets the current output string. + * + * @return the output string + */ public String getOutputString(){ return outputString; } + /** + * Gets the current keyword. + * + * @return the keyword + */ public String getKeyword(){ return keyword; } diff --git a/src/main/java/com/mattrixwv/cipherstream/polysubstitution/Hill.java b/src/main/java/com/mattrixwv/cipherstream/polysubstitution/Hill.java index 994868c..0eb2f16 100644 --- a/src/main/java/com/mattrixwv/cipherstream/polysubstitution/Hill.java +++ b/src/main/java/com/mattrixwv/cipherstream/polysubstitution/Hill.java @@ -1,7 +1,23 @@ //CipherStreamJava/src/main/java/com/mattrixwv/cipherstream/polysubstitution/Hill.java //Mattrixwv // Created: 01-31-22 -//Modified: 05-04-23 +//Modified: 08-11-24 +/* + Copyright (C) 2024 Mattrixwv + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ package com.mattrixwv.cipherstream.polysubstitution; @@ -18,20 +34,39 @@ import com.mattrixwv.matrix.exceptions.InvalidGeometryException; import com.mattrixwv.matrix.exceptions.InvalidScalarException; +/** + * Implements the Hill cipher for encoding and decoding messages using matrix operations. + *

+ * The Hill cipher is a polygraphic substitution cipher that uses linear algebra to encrypt and decrypt + * messages. It operates on blocks of text by representing them as vectors and applying matrix transformations. + *

+ */ public class Hill{ private static final Logger logger = LoggerFactory.getLogger(Hill.class); - //Fields - protected String inputString; //The message that needs to be encoded/decoded - protected String outputString; //The encoded/decoded message - protected char characterToAdd; //The keyword used to create the grid - protected ModMatrix key; //The matrix used perform the encoding/decoding - //Settings - protected boolean preserveCapitals; //Persist capitals in the output string - protected boolean preserveWhitespace; //Persist whitespace in the output string - protected boolean preserveSymbols; //Persist symbols in the output string + //?Fields + /** The message that needs to be encoded/decoded */ + protected String inputString; + /** The encoded/decoded message */ + protected String outputString; + /** The keyword used to create the grid */ + protected char characterToAdd; + /** The matrix used perform the encoding/decoding */ + protected ModMatrix key; + //?Settings + /** Persist capitals in the output string */ + protected boolean preserveCapitals; + /** Persist whitespace in the output string */ + protected boolean preserveWhitespace; + /** Persist symbols in the output string */ + protected boolean preserveSymbols; - //Validate and set the key + /** + * Sets the key matrix for the Hill cipher after validating it. + * + * @param key the matrix to be used for encoding/decoding + * @throws InvalidKeyException if the key is not a square matrix, or does not have an inverse modulo 26 + */ protected void setKey(ModMatrix key) throws InvalidKeyException{ logger.debug("Setting key"); @@ -60,7 +95,13 @@ public class Hill{ logger.debug("key\n{}", key); this.key = new ModMatrix(key); } - //Validate and set the input string + /** + * Prepares and validates the input string for encoding by removing unwanted characters + * and ensuring the length is appropriate. + * + * @param inputString the message to be encoded + * @throws InvalidInputException if the input is null, blank, or its length is not a multiple of the matrix size + */ protected void setInputStringEncode(String inputString) throws InvalidInputException{ logger.debug("Setting input string for encoding"); @@ -111,6 +152,13 @@ public class Hill{ throw new InvalidInputException("Input cannot be blank"); } } + /** + * Prepares and validates the input string for decoding by removing unwanted characters + * and ensuring the length is appropriate. + * + * @param inputString the message to be decoded + * @throws InvalidInputException if the input is null, blank, or its length is not a multiple of the matrix size + */ protected void setInputStringDecode(String inputString) throws InvalidInputException{ logger.debug("Setting input string for decoding"); @@ -145,7 +193,11 @@ public class Hill{ throw new InvalidInputException("Length of input string must be a multiple of the number of rows in the key"); } } - //Get a perfectly clean copy of input string + /** + * Returns a clean version of the input string with only uppercase letters. + * + * @return the cleaned input string + */ protected String getCleanInputString(){ logger.debug("Cleaning inputString"); @@ -154,7 +206,12 @@ public class Hill{ return cleanInputString; } - //Validate and set character to add + /** + * Sets the character used for padding the input string. + * + * @param characterToAdd the character to be used for padding + * @throws InvalidCharacterException if the character is not a letter + */ protected void setCharacterToAdd(char characterToAdd) throws InvalidCharacterException{ logger.debug("Setting character to add {}", characterToAdd); @@ -173,7 +230,11 @@ public class Hill{ logger.debug("Cleaned character {}", characterToAdd); this.characterToAdd = characterToAdd; } - //Add capitalization, whitespace, and symbols to the output based on the input + /** + * Restores capitalization, whitespace, and symbols to the output string based on the original input string. + * + * @return the polished output string + */ protected String polishOutputString(){ logger.debug("Polishing output string"); @@ -203,7 +264,11 @@ public class Hill{ logger.debug("Polished string '{}'", cleanString); return cleanString; } - //Get vectors representing the input string + /** + * Converts the cleaned input string into a list of column vectors based on the key matrix size. + * + * @return a list of vectors representing the input string + */ protected ArrayList getInputVectors(){ logger.debug("Generating input vectors"); @@ -237,7 +302,12 @@ public class Hill{ //Return the array of vectors return vectors; } - //Get the string represented by the vectors that were passed in + /** + * Converts a list of vectors back into a string representation. + * + * @param outputVectors the list of vectors to be converted + * @return the resulting string + */ protected String getOutputFromVectors(ArrayList outputVectors){ logger.debug("Turning vectors into a string"); @@ -257,7 +327,9 @@ public class Hill{ logger.debug("Converted string '{}'", convertedString); return convertedString; } - //Encode inputString and store the value in outputString + /** + * Encodes the input string using the provided key matrix and stores the result in outputString. + */ protected void encode(){ logger.debug("Encoding"); @@ -281,7 +353,9 @@ public class Hill{ //Add the extra characters back to the output and remove the added characters outputString = polishOutputString(); } - //Decode inputString and store the value in outputString + /** + * Decodes the input string using the provided key matrix and stores the result in outputString. + */ protected void decode(){ logger.debug("Decoding"); @@ -308,7 +382,12 @@ public class Hill{ outputString = polishOutputString(); } - //Constructors + //?Constructors + /** + * Default constructor initializing the cipher with default settings. + * + * @throws InvalidCharacterException if the default padding character is invalid + */ public Hill() throws InvalidCharacterException{ preserveCapitals = false; preserveWhitespace = false; @@ -316,6 +395,14 @@ public class Hill{ setCharacterToAdd('x'); reset(); } + /** + * Constructor initializing the cipher with specified settings. + * + * @param preserveCapitals if true, preserves capitals in the output string + * @param preserveWhitespace if true, preserves whitespace in the output string + * @param preserveSymbols if true, preserves symbols in the output string + * @throws InvalidCharacterException if the default padding character is invalid + */ public Hill(boolean preserveCapitals, boolean preserveWhitespace, boolean preserveSymbols) throws InvalidCharacterException{ this.preserveCapitals = preserveCapitals; this.preserveWhitespace = preserveWhitespace; @@ -323,6 +410,15 @@ public class Hill{ setCharacterToAdd('x'); reset(); } + /** + * Constructor initializing the cipher with specified settings and padding character. + * + * @param preserveCapitals if true, preserves capitals in the output string + * @param preserveWhitespace if true, preserves whitespace in the output string + * @param preserveSymbols if true, preserves symbols in the output string + * @param characterToAdd the character to use for padding + * @throws InvalidCharacterException if the padding character is invalid + */ public Hill(boolean preserveCapitals, boolean preserveWhitespace, boolean preserveSymbols, char characterToAdd) throws InvalidCharacterException{ this.preserveCapitals = preserveCapitals; this.preserveWhitespace = preserveWhitespace; @@ -331,20 +427,54 @@ public class Hill{ reset(); } - //Encode inputString using the provided key + /** + * Encodes the input string using the provided key matrix and returns the encoded string. + * + * @param key the matrix to use for encoding + * @param inputString the message to encode + * @return the encoded message + * @throws InvalidKeyException if the key is invalid + * @throws InvalidInputException if the input is invalid + */ public String encode(int[][] key, String inputString) throws InvalidKeyException, InvalidInputException{ return encode(new ModMatrix(key, 26), inputString); } + /** + * Encodes the input string using the provided key matrix and returns the encoded string. + * + * @param key the matrix to use for encoding + * @param inputString the message to encode + * @return the encoded message + * @throws InvalidKeyException if the key is invalid + * @throws InvalidInputException if the input is invalid + */ public String encode(ModMatrix key, String inputString) throws InvalidKeyException, InvalidInputException{ setKey(key); setInputStringEncode(inputString); encode(); return outputString; } - //Decode inputString using the provided key + /** + * Decodes the input string using the provided key matrix and returns the decoded string. + * + * @param key the matrix to use for decoding + * @param inputString the message to decode + * @return the decoded message + * @throws InvalidKeyException if the key is invalid + * @throws InvalidInputException if the input is invalid + */ public String decode(int[][] key, String inputString) throws InvalidKeyException, InvalidInputException{ return decode(new ModMatrix(key, 26), inputString); } + /** + * Decodes the input string using the provided key matrix and returns the decoded string. + * + * @param key the matrix to use for decoding + * @param inputString the message to decode + * @return the decoded message + * @throws InvalidKeyException if the key is invalid + * @throws InvalidInputException if the input is invalid + */ public String decode(ModMatrix key, String inputString) throws InvalidKeyException, InvalidInputException{ setKey(key); setInputStringDecode(inputString); @@ -352,7 +482,9 @@ public class Hill{ return outputString; } - //Makes sure all variables are empty + /** + * Resets the Hill cipher by clearing all variables and setting the key to an empty matrix. + */ public void reset(){ logger.debug("Resetting fields"); @@ -361,13 +493,28 @@ public class Hill{ key = new ModMatrix(26); } - //Getters + //?Getters + /** + * Returns the input string. + * + * @return the input string + */ public String getInputString(){ return inputString; } + /** + * Returns the output string. + * + * @return the output string + */ public String getOutputString(){ return outputString; } + /** + * Returns the key matrix used for encoding or decoding. + * + * @return the key matrix + */ public ModMatrix getKey(){ return key; } diff --git a/src/main/java/com/mattrixwv/cipherstream/polysubstitution/LargePolybiusSquare.java b/src/main/java/com/mattrixwv/cipherstream/polysubstitution/LargePolybiusSquare.java index f09bcb5..bd9a884 100644 --- a/src/main/java/com/mattrixwv/cipherstream/polysubstitution/LargePolybiusSquare.java +++ b/src/main/java/com/mattrixwv/cipherstream/polysubstitution/LargePolybiusSquare.java @@ -1,7 +1,23 @@ //CipherStreamJava/src/main/java/com/mattrixwv/cipherstream/polysubstitution/LargePolybiusSquare.java //Mattrixwv // Created: 04-21-23 -// Modified: 05-04-23 +// Modified: 08-11-24 +/* + Copyright (C) 2024 Mattrixwv + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ package com.mattrixwv.cipherstream.polysubstitution; @@ -15,11 +31,18 @@ import com.mattrixwv.cipherstream.exceptions.InvalidInputException; import com.mattrixwv.cipherstream.exceptions.InvalidKeywordException; +/** + * Represents the Polybius square cipher encryption and decryption. + * The Polybius square cipher is a classical encryption method that uses a 6x6 grid + * to encode and decode messages based on the positions of letters and numbers in the grid. + */ public class LargePolybiusSquare extends PolybiusSquare{ private static final Logger logger = LoggerFactory.getLogger(LargePolybiusSquare.class); - //Create the grid from the keyword + /** + * Creates the grid from the keyword. + */ @Override protected void createGrid(){ logger.debug("Creating grid"); @@ -31,7 +54,13 @@ public class LargePolybiusSquare extends PolybiusSquare{ } } } - //Strips invalid characters from the string that needs encoded/decoded + /** + * Strips invalid characters from the string that needs encoding/decoding. + * + * @param inputString the input string to be cleaned + * @throws InvalidCharacterException if an invalid character is found + * @throws InvalidInputException if the input string is invalid + */ @Override protected void setInputStringEncode(String inputString) throws InvalidCharacterException, InvalidInputException{ if(inputString == null){ @@ -75,7 +104,11 @@ public class LargePolybiusSquare extends PolybiusSquare{ throw new InvalidInputException("Input must contain at least 1 letter"); } } - //Returns the input string ready for encoding + /** + * Returns the input string ready for encoding. + * + * @return the prepared input string + */ @Override protected String getPreparedInputStringEncode(){ logger.debug("Preparing input string for encoding"); @@ -87,7 +120,11 @@ public class LargePolybiusSquare extends PolybiusSquare{ return cleanString; } - //Strips invalid characters from the keyword and creates the grid + /** + * Strips invalid characters from the keyword and creates the grid. + * + * @param keyword the keyword to be processed + */ @Override protected void setKeyword(String keyword) throws InvalidKeywordException{ if(keyword == null){ @@ -116,7 +153,11 @@ public class LargePolybiusSquare extends PolybiusSquare{ //Create the grid from the sanitized keyword createGrid(); } - //Adds characters that aren't letters to the output + /** + * Adds characters that aren't letters to the output during encoding. + * + * @param cleanString the cleaned string to be formatted + */ @Override protected void addCharactersToCleanStringEncode(String cleanString){ logger.debug("Formatting output string"); @@ -144,6 +185,11 @@ public class LargePolybiusSquare extends PolybiusSquare{ outputString = fullOutput.toString(); logger.debug("Saving output string {}", outputString); } + /** + * Adds characters that aren't letters to the output during decoding. + * + * @param cleanString the cleaned string to be formatted + */ @Override protected void addCharactersToCleanStringDecode(String cleanString){ logger.debug("Formatting output string"); @@ -172,7 +218,9 @@ public class LargePolybiusSquare extends PolybiusSquare{ logger.debug("Saving output string {}", outputString); } - //Makes sure all variables are empty + /** + * Resets all variables to their default values. + */ @Override public void reset(){ logger.debug("Resetting"); @@ -183,10 +231,22 @@ public class LargePolybiusSquare extends PolybiusSquare{ keyword = ""; } - //Constructors + //?Constructors + /** + * Constructs a PolybiusSquare cipher instance with default settings. + * + * @throws InvalidCharacterException if default characters are invalid + */ public LargePolybiusSquare() throws InvalidCharacterException{ super(); } + /** + * Constructs a PolybiusSquare cipher instance with specified settings. + * + * @param preserveWhitespace whether to preserve whitespace + * @param preserveSymbols whether to preserve symbols + * @throws InvalidCharacterException if default characters are invalid + */ public LargePolybiusSquare(boolean preserveWhitespace, boolean preserveSymbols) throws InvalidCharacterException{ super(preserveWhitespace, preserveSymbols); } diff --git a/src/main/java/com/mattrixwv/cipherstream/polysubstitution/Morse.java b/src/main/java/com/mattrixwv/cipherstream/polysubstitution/Morse.java index f2b2131..6893a70 100644 --- a/src/main/java/com/mattrixwv/cipherstream/polysubstitution/Morse.java +++ b/src/main/java/com/mattrixwv/cipherstream/polysubstitution/Morse.java @@ -1,7 +1,23 @@ //CipherStreamJava/src/main/java/com/mattrixwv/CipherStreamJava/Morse.java //Mattrixwv // Created: 07-28-21 -//Modified: 05-04-23 +//Modified: 08-11-24 +/* + Copyright (C) 2024 Mattrixwv + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ package com.mattrixwv.cipherstream.polysubstitution; @@ -15,17 +31,28 @@ import org.slf4j.LoggerFactory; import com.mattrixwv.cipherstream.exceptions.InvalidInputException; +/** + * A class to handle encoding and decoding of Morse code. + *

+ * This class provides methods to encode a string into Morse code and decode Morse code back into a string. + * It supports alphanumeric characters (A-Z, 0-9) and validates input to ensure it contains valid characters. + *

+ */ public class Morse{ private static final Logger logger = LoggerFactory.getLogger(Morse.class); - //Code representations + //?Code representations + /** Morse code representations for letters A-Z */ private static final String[] letters = { ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", //A-L "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--.." //M-Z }; + /** Morse code representations for digits 0-9 */ private static final String[] numbers = { "-----", ".----", "..---", "...--", "....-", ".....", "-....", "--...", "---..", "----." //0-9 }; - private static final Map map; //The map to help convert from Morse to letters and numbers + /** The map to help convert from Morse to letters and numbers */ + private static final Map map; + /** Initialize the Morse Code map */ static{ //Setup the map map = new HashMap<>(); @@ -38,12 +65,22 @@ public class Morse{ map.put(number, (char)('0' + cnt)); } } - //Fields - protected String inputString; //The string that needs encoded/decoded - protected String outputString; //The encoded/decoded message + //?Fields + /** The string that needs encoded/decoded */ + protected String inputString; + /** The encoded/decoded message */ + protected String outputString; - //Validate and set the input string for encoding + /** + * Validates and prepares the input string for encoding. + *

+ * This method converts the input string to uppercase, removes all non-alphanumeric characters, and stores the cleaned string. + *

+ * + * @param inputString the string to be encoded + * @throws InvalidInputException if the input string is null or contains invalid characters + */ protected void setInputStringEncode(String inputString){ logger.debug("Setting input string for encoding '{}'", inputString); @@ -70,7 +107,15 @@ public class Morse{ //Save the input this.inputString = inputString; } - //Validate and set the input string for decoding + /** + * Validates and prepares the input string for decoding. + *

+ * This method ensures that the input string contains only valid Morse code characters (dots, dashes, and spaces). + *

+ * + * @param inputString the Morse code string to be decoded + * @throws InvalidInputException if the input string is null or contains invalid Morse code characters + */ protected void setInputStringDecode(String inputString){ logger.debug("Setting input string for decoding '{}'", inputString); @@ -94,7 +139,14 @@ public class Morse{ logger.debug("Saving"); this.inputString = inputString; } - //Encodes the inputString and stores the result in outputString + /** + * Encodes the {@code inputString} into Morse code. + *

+ * This method converts each alphanumeric character in the input string to its Morse code representation and stores the result. + *

+ * + * @throws InvalidInputException if the input string contains characters that cannot be encoded + */ protected void encode(){ logger.debug("Encoding"); @@ -123,7 +175,14 @@ public class Morse{ this.outputString = output.toString(); logger.debug("Saving encoded string '{}'", outputString); } - //Decodes the inputString and stores the result in outputString + /** + * Decodes the {@code inputString} from Morse code to plain text. + *

+ * This method converts each Morse code sequence in the input string back to its corresponding alphanumeric character. + *

+ * + * @throws InvalidInputException if the input string contains invalid Morse code sequences + */ protected void decode(){ logger.debug("Decoding"); @@ -149,19 +208,40 @@ public class Morse{ } - //Constructor + //?Constructor + /** + * Resets the class by clearing the input and output strings. + */ public Morse(){ reset(); } - //Sets the inputString and encodes the message + /** + * Encodes the given input string into Morse code. + *

+ * This method validates the input string, encodes it, and returns the Morse code representation. + *

+ * + * @param inputString the string to be encoded + * @return the Morse code representation of the input string + * @throws InvalidInputException if the input string contains invalid characters + */ public String encode(String inputString){ setInputStringEncode(inputString); encode(); return outputString; } - //Sets the inputString and decodes the message + /** + * Decodes the given Morse code string into plain text. + *

+ * This method validates the Morse code input, decodes it, and returns the plain text representation. + *

+ * + * @param inputString the Morse code string to be decoded + * @return the decoded plain text representation + * @throws InvalidInputException if the input string contains invalid Morse code sequences + */ public String decode(String inputString){ setInputStringDecode(inputString); decode(); @@ -169,14 +249,26 @@ public class Morse{ } - //Getters + //?Getters + /** + * Returns the current input string. + * + * @return the current input string + */ public String getInputString(){ return inputString; } + /** + * Returns the current output string. + * + * @return the current output string + */ public String getOutputString(){ return outputString; } - //Makes sure all variables are empty + /** + * Resets the internal fields to their default values. + */ public void reset(){ logger.debug("Resetting"); diff --git a/src/main/java/com/mattrixwv/cipherstream/polysubstitution/Playfair.java b/src/main/java/com/mattrixwv/cipherstream/polysubstitution/Playfair.java index 436d757..06b9fe8 100644 --- a/src/main/java/com/mattrixwv/cipherstream/polysubstitution/Playfair.java +++ b/src/main/java/com/mattrixwv/cipherstream/polysubstitution/Playfair.java @@ -1,7 +1,23 @@ //CipherStreamJava/src/main/java/com/mattrixwv/cipherstream/polysubstitution/Playfair.java //Matthew Ellison // Created: 07-30-21 -//Modified: 05-04-23 +//Modified: 08-11-24 +/* + Copyright (C) 2024 Mattrixwv + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ package com.mattrixwv.cipherstream.polysubstitution; @@ -15,40 +31,77 @@ import com.mattrixwv.cipherstream.exceptions.InvalidInputException; import com.mattrixwv.cipherstream.exceptions.InvalidKeywordException; +/** + * Represents the Playfair cipher encryption and decryption. + * The Playfair cipher is a digraph substitution cipher that encrypts pairs of letters. + */ public class Playfair{ private static final Logger logger = LoggerFactory.getLogger(Playfair.class); - //A class representing the location of a character in the grid + /** A class representing the location of a character in the grid */ protected class CharLocation{ + /** The x location in the grid */ protected int x; + /** The y location in the grid */ protected int y; + /** + * Constructs a CharLocation with the specified x and y coordinates. + * + * @param x the x-coordinate of the character's location + * @param y the y-coordinate of the character's location + */ public CharLocation(int x, int y){ this.x = x; this.y = y; } + /** + * Returns the x-coordinate of the character's location. + * + * @return the x-coordinate + */ public int getX(){ return x; } + /** + * Returns the y-coordinate of the character's location. + * + * @return the y-coordinate + */ public int getY(){ return y; } } - //Fields - protected String inputString; //The message that needs to be encoded/decoded - protected String outputString; //The encoded/decoded message - protected String keyword; //The keyword used to create the grid - protected char[][] grid; //The grid used to encode/decode the message - protected char replaced; //The letter that will need to be replaced in the grid and any input string or keyword - protected char replacer; //The letter that replaced replaced in the input string or keyword - protected char doubled; //The letter that will be placed between double letters in the input string if necessary or to make the string length even - //Settings - protected boolean preserveCapitals; //Persist captials in the output string - protected boolean preserveWhitespace; //Persist whitespace in the output string - protected boolean preserveSymbols; //Persist symbols in the output string + //?Fields + /** The message that needs to be encoded/decoded */ + protected String inputString; + /** The encoded/decoded message */ + protected String outputString; + /** The keyword used to create the grid */ + protected String keyword; + /** The grid used to encode/decode the message */ + protected char[][] grid; + /** The letter that will need to be replaced in the grid and any input string or keyword */ + protected char replaced; + /** The letter that replaced replaced in the input string or keyword */ + protected char replacer; + /** The letter that will be placed between double letters in the input string if necessary or to make the string length even */ + protected char doubled; + //?Settings + /** Persist capitals in the output string */ + protected boolean preserveCapitals; + /** Persist whitespace in the output string */ + protected boolean preserveWhitespace; + /** Persist symbols in the output string */ + protected boolean preserveSymbols; - //Set the doubled character + /** + * Sets the doubled character. + * + * @param doubled the character to be used as the doubled character + * @throws InvalidCharacterException if the character is not a letter or is invalid + */ protected void setDoubled(char doubled) throws InvalidCharacterException{ logger.debug("Setting doubled"); logger.debug("Original character {}", doubled); @@ -80,7 +133,12 @@ public class Playfair{ logger.debug("Setting doubled to {}", doubled); this.doubled = doubled; } - //Set the replacer character + /** + * Sets the replacer character. + * + * @param replacer the character to replace the replaced character + * @throws InvalidCharacterException if the character is not a letter or is invalid + */ protected void setReplacer(char replacer) throws InvalidCharacterException{ logger.debug("Setting replacer"); logger.debug("Original character {}", replacer); @@ -112,7 +170,12 @@ public class Playfair{ logger.debug("Setting replacer to {}", replacer); this.replacer = replacer; } - //Set the replaced character + /** + * Sets the replaced character. + * + * @param replaced the character to be replaced + * @throws InvalidCharacterException if the character is not a letter or is invalid + */ protected void setReplaced(char replaced) throws InvalidCharacterException{ logger.debug("Setting replaced"); logger.debug("Original character {}", replaced); @@ -144,7 +207,9 @@ public class Playfair{ logger.debug("Setting replaced to {}", replaced); this.replaced = replaced; } - //Create the grid from the keyword + /** + * Creates the grid from the keyword. + */ protected void createGrid(){ logger.debug("Creating grid from keyword"); @@ -158,7 +223,14 @@ public class Playfair{ logger.debug("Grid\n{}", getGrid()); } - //Strips invalid characters from the string that needs encoded/decoded + /** + * Strips invalid characters from the string that needs encoding/decoding. + * + * @param inputString the input string to be cleaned + * @param encoding true if encoding, false if decoding + * @throws InvalidCharacterException if an invalid character is found + * @throws InvalidInputException if the input string is invalid + */ protected void setInputString(String inputString, boolean encoding) throws InvalidCharacterException, InvalidInputException{ logger.debug("Setting input string"); @@ -214,6 +286,11 @@ public class Playfair{ throw new InvalidInputException("Input must have at least 1 letter"); } } + /** + * Cleans up the input string for encoding. + * + * @param inputString the input string to be cleaned + */ protected void setInputStringEncode(String inputString){ logger.debug("Cleaning up input string for encoding"); @@ -286,7 +363,11 @@ public class Playfair{ this.inputString = cleanInput.toString(); logger.debug("Cleaned input string '{}'", this.inputString); } - //Returns the input string ready for encoding + /** + * Returns the input string ready for encoding. + * + * @return the prepared input string + */ protected String getPreparedInputString(){ logger.debug("Getting input string ready for encoding"); @@ -297,7 +378,12 @@ public class Playfair{ return cleanString; } - //Strips invalid characters from the keyword and creates the grid + /** + * Strips invalid characters from the keyword and creates the grid. + * + * @param keyword the keyword to be processed + * @throws InvalidKeywordException if the keyword is invalid + */ protected void setKeyword(String keyword) throws InvalidKeywordException{ logger.debug("Setting keyword"); @@ -333,7 +419,13 @@ public class Playfair{ //Create the grid from the sanitized keyword createGrid(); } - //Returns the location of the given character in the grid + /** + * Returns the location of the given character in the grid. + * + * @param letter the character whose location is to be found + * @return the location of the character in the grid + * @throws InvalidInputException if the character is not found in the grid + */ protected CharLocation findChar(char letter) throws InvalidInputException{ logger.debug("Finding character in grid {}", letter); @@ -350,7 +442,13 @@ public class Playfair{ //If it was not found something went wrong throw new InvalidInputException("The character '" + letter + "' was not found in the grid"); } - //Returns the location in the grid of x and y, adjusting for out of bounds + /** + * Returns the character in the grid at the specified coordinates. + * + * @param x the x-coordinate + * @param y the y-coordinate + * @return the character at the specified coordinates + */ protected char getGridChar(int x, int y){ logger.debug("Getting character from grid[{}][{}]", x, y); @@ -365,7 +463,11 @@ public class Playfair{ logger.debug("Character {}", letter); return letter; } - //Adds characters that aren't letters to the output + /** + * Adds characters that aren't letters to the output. + * + * @param cleanString the cleaned string to be formatted + */ protected void addCharactersToCleanString(String cleanString){ logger.debug("Formatting output string"); @@ -394,7 +496,11 @@ public class Playfair{ outputString = fullOutput.toString(); logger.debug("Formatted output '{}'", outputString); } - //Encodes inputString using the Playfair cipher and stores the result in outputString + /** + * Encodes the input string using the Playfair cipher and stores the result in the output string. + * + * @throws InvalidInputException if the input string is invalid + */ protected void encode() throws InvalidInputException{ logger.debug("Encoding"); @@ -438,7 +544,11 @@ public class Playfair{ //Add other characters to the output string addCharactersToCleanString(output.toString()); } - //Decodes inputString using the Playfair cipher and stores the result in outputString + /** + * Decodes the input string using the Playfair cipher and stores the result in the output string. + * + * @throws InvalidInputException if the input string is invalid + */ protected void decode() throws InvalidInputException{ logger.debug("Decoding"); @@ -483,7 +593,12 @@ public class Playfair{ addCharactersToCleanString(output.toString()); } - //Constructor + //?Constructor + /** + * Constructs a Playfair cipher instance with default settings. + * + * @throws InvalidCharacterException if default characters are invalid + */ public Playfair() throws InvalidCharacterException{ reset(); preserveCapitals = false; @@ -493,6 +608,14 @@ public class Playfair{ setReplacer('i'); setDoubled('x'); } + /** + * Constructs a Playfair cipher instance with specified settings. + * + * @param preserveCapitals whether to preserve capital letters + * @param preserveWhitespace whether to preserve whitespace + * @param preserveSymbols whether to preserve symbols + * @throws InvalidCharacterException if default characters are invalid + */ public Playfair(boolean preserveCapitals, boolean preserveWhitespace, boolean preserveSymbols) throws InvalidCharacterException{ reset(); this.preserveCapitals = preserveCapitals; @@ -502,6 +625,17 @@ public class Playfair{ setReplacer('i'); setDoubled('x'); } + /** + * Constructs a Playfair cipher instance with specified settings and characters. + * + * @param preserveCapitals whether to preserve capital letters + * @param preserveWhitespace whether to preserve whitespace + * @param preserveSymbols whether to preserve symbols + * @param replaced the character to be replaced + * @param replacer the character to replace the replaced character + * @param doubled the character to use for doubled letters + * @throws InvalidCharacterException if any character is invalid + */ public Playfair(boolean preserveCapitals, boolean preserveWhitespace, boolean preserveSymbols, char replaced, char replacer, char doubled) throws InvalidCharacterException{ reset(); this.preserveCapitals = preserveCapitals; @@ -512,7 +646,15 @@ public class Playfair{ setDoubled(doubled); } - //Sets the keyword and inputString and encodes the message + /** + * Sets the keyword and input string and encodes the message. + * + * @param keyword the keyword for the cipher + * @param input the message to encode + * @return the encoded message + * @throws InvalidCharacterException if any character is invalid + * @throws InvalidInputException if the input string is invalid + */ public String encode(String keyword, String input) throws InvalidCharacterException, InvalidInputException{ reset(); setKeyword(keyword); @@ -520,7 +662,15 @@ public class Playfair{ encode(); return outputString; } - //Sets the keyword and inputString and decodes the message + /** + * Sets the keyword and input string and decodes the message. + * + * @param keyword the keyword for the cipher + * @param input the encoded message to decode + * @return the decoded message + * @throws InvalidCharacterException if any character is invalid + * @throws InvalidInputException if the input string is invalid + */ public String decode(String keyword, String input) throws InvalidCharacterException, InvalidInputException{ reset(); setKeyword(keyword); @@ -529,7 +679,9 @@ public class Playfair{ return outputString; } - //Makes sure all variables are empty + /** + * Resets all variables to their default values. + */ public void reset(){ logger.debug("Resetting fields"); @@ -538,25 +690,60 @@ public class Playfair{ outputString = ""; keyword = ""; } - //Getters + //?Getters + /** + * Returns the replaced character. + * + * @return the replaced character + */ public char getReplaced(){ return replaced; } + /** + * Returns the replacer character. + * + * @return the replacer character + */ public char getReplacer(){ return replacer; } + /** + * Returns the doubled character. + * + * @return the doubled character + */ public char getDoubled(){ return doubled; } + /** + * Returns the keyword used in the cipher. + * + * @return the keyword + */ public String getKeyword(){ return keyword; } + /** + * Returns the input string that was set for encoding/decoding. + * + * @return the input string + */ public String getInputString(){ return inputString; } + /** + * Returns the output string after encoding/decoding. + * + * @return the output string + */ public String getOutputString(){ return outputString; } + /** + * Return the grid used for encoding/decoding. + * + * @return the grid as a string + */ public String getGrid(){ logger.debug("Creating string from grid"); diff --git a/src/main/java/com/mattrixwv/cipherstream/polysubstitution/PolybiusSquare.java b/src/main/java/com/mattrixwv/cipherstream/polysubstitution/PolybiusSquare.java index b070268..e8895ab 100644 --- a/src/main/java/com/mattrixwv/cipherstream/polysubstitution/PolybiusSquare.java +++ b/src/main/java/com/mattrixwv/cipherstream/polysubstitution/PolybiusSquare.java @@ -1,7 +1,23 @@ //CipherStreamJava/src/main/java/com/mattrixwv/cipherstream/polysubstitution/PolybiusSquare.java //Mattrixwv // Created: 01-04-22 -//Modified: 05-04-23 +//Modified: 08-11-24 +/* + Copyright (C) 2024 Mattrixwv + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ package com.mattrixwv.cipherstream.polysubstitution; @@ -15,38 +31,74 @@ import com.mattrixwv.cipherstream.exceptions.InvalidInputException; import com.mattrixwv.cipherstream.exceptions.InvalidKeywordException; +/** + * Represents the Polybius square cipher encryption and decryption. + * The Polybius square cipher is a classical encryption method that uses a 5x5 grid + * to encode and decode messages based on the positions of letters in the grid. + */ public class PolybiusSquare{ private static final Logger logger = LoggerFactory.getLogger(PolybiusSquare.class); - //A class representing the location of a character in the grid + /** A class representing the location of a character in the grid */ protected class CharLocation{ + /** The x location in the grid */ private int x; + /** The y location in the grid */ private int y; + /** + * Constructs a CharLocation with the specified x and y coordinates. + * + * @param x the x-coordinate of the character's location + * @param y the y-coordinate of the character's location + */ public CharLocation(int x, int y){ this.x = x; this.y = y; } + /** + * Returns the x-coordinate of the character's location. + * + * @return the x-coordinate + */ public int getX(){ return x; } + /** + * Returns the y-coordinate of the character's location. + * + * @return the y-coordinate + */ public int getY(){ return y; } } - //Fields - protected String inputString; //The message that needs to be encoded/decoded - protected String outputString; //The encoded/decoded message - protected String keyword; //The keyword used to create the grid - protected char[][] grid; //The grid used to encode/decode the message - protected char replaced; //The letter that will need to be replaced in the grid and any input string or keyword - protected char replacer; //The letter that replaces replaced in the input string or keyword - //Settings - protected boolean preserveWhitespace; //Persist whitespace in the output string - protected boolean preserveSymbols; //Persist symbols in the output string + //?Fields + /** The message that needs to be encoded/decoded */ + protected String inputString; + /** The encoded/decoded message */ + protected String outputString; + /** The keyword used to create the grid */ + protected String keyword; + /** The grid used to encode/decode the message */ + protected char[][] grid; + /** The letter that will need to be replaced in the grid and any input string or keyword */ + protected char replaced; + /** The letter that replaces replaced in the input string or keyword */ + protected char replacer; + //?Settings + /** Persist whitespace in the output string */ + protected boolean preserveWhitespace; + /** Persist symbols in the output string */ + protected boolean preserveSymbols; - //Setting the character to be replaced + /** + * Sets the replaced character. + * + * @param replaced the character to be replaced + * @throws InvalidCharacterException if the character is not a letter or is invalid + */ protected void setReplaced(char replaced) throws InvalidCharacterException{ logger.debug("Setting replaced"); logger.debug("Original character {}", replaced); @@ -63,7 +115,12 @@ public class PolybiusSquare{ this.replaced = Character.toUpperCase(replaced); logger.debug("Cleaned character {}", this.replaced); } - //Setting the character that replaces replaced + /** + * Sets the replacer character. + * + * @param replacer the character the replaces replaced + * @throws InvalidCharacterException if the character is not a letter or is invalid + */ protected void setReplacer(char replacer) throws InvalidCharacterException{ logger.debug("Setting replacer"); logger.debug("Original character {}", replacer); @@ -80,7 +137,9 @@ public class PolybiusSquare{ this.replacer = Character.toUpperCase(replacer); logger.debug("Cleaned character {}", this.replacer); } - //Create the grid from the keyword + /** + * Creates the grid from the keyword. + */ protected void createGrid(){ logger.debug("Creating grid from keyword"); @@ -93,7 +152,13 @@ public class PolybiusSquare{ logger.debug("Created grid\n{}", getGrid()); } - //Strips invalid characters from the string that needs encoded/decoded + /** + * Strips invalid characters from the string that needs encoding/decoding. + * + * @param inputString the input string to be cleaned + * @throws InvalidCharacterException if an invalid character is found + * @throws InvalidInputException if the input string is invalid + */ protected void setInputStringEncode(String inputString) throws InvalidCharacterException, InvalidInputException{ if(inputString == null){ throw new InvalidInputException("Input cannot be null"); @@ -148,6 +213,13 @@ public class PolybiusSquare{ throw new InvalidInputException("Input must contain at least 1 letter"); } } + /** + * Strips invalid characters from the string that needs decoding. + * + * @param inputString the input string to be cleaned + * @throws InvalidCharacterException if an invalid character is found + * @throws InvalidInputException if the input string is invalid + */ protected void setInputStringDecode(String inputString) throws InvalidCharacterException, InvalidInputException{ if(inputString == null){ throw new InvalidInputException("Input cannot be null"); @@ -193,7 +265,11 @@ public class PolybiusSquare{ throw new InvalidInputException("Input must contain at least 1 letter"); } } - //Returns the input string ready for encoding + /** + * Returns the input string ready for encoding. + * + * @return the prepared input string + */ protected String getPreparedInputStringEncode(){ logger.debug("Preparing input string for encoding"); @@ -203,6 +279,11 @@ public class PolybiusSquare{ logger.debug("Prepared string '{}'", cleanString); return cleanString; } + /** + * Returns the input string ready for decoding. + * + * @return the prepared input string + */ protected String getPreparedInputStringDecode(){ logger.debug("Preparing input string for decoding"); @@ -211,7 +292,11 @@ public class PolybiusSquare{ logger.debug("Prepared string '{}'", cleanString); return cleanString; } - //Strips invalid characters from the keyword and creates the grid + /** + * Strips invalid characters from the keyword and creates the grid. + * + * @param keyword the keyword to be processed + */ protected void setKeyword(String keyword){ if(keyword == null){ throw new InvalidKeywordException("Keyword cannot be null"); @@ -244,7 +329,13 @@ public class PolybiusSquare{ //Create the grid from the sanitized keyword createGrid(); } - //Returns the location of the given charcter in the grid + /** + * Returns the location of the given character in the grid. + * + * @param letter the character whose location is to be found + * @return the location of the character in the grid + * @throws InvalidInputException if the character is not found in the grid + */ protected CharLocation findChar(char letter) throws InvalidInputException{ logger.debug("Finding {} in grid", letter); @@ -260,7 +351,11 @@ public class PolybiusSquare{ //If it was not found something went wrong throw new InvalidInputException("The character '" + letter + "' was not found in the grid"); } - //Adds characters that aren't letters to the output + /** + * Adds characters that aren't letters to the output during encoding. + * + * @param cleanString the cleaned string to be formatted + */ protected void addCharactersToCleanStringEncode(String cleanString){ logger.debug("Formatting output string for encoding"); @@ -287,6 +382,11 @@ public class PolybiusSquare{ outputString = fullOutput.toString(); logger.debug("Formatted output '{}'", outputString); } + /** + * Adds characters that aren't letters to the output during decoding. + * + * @param cleanString the cleaned string to be formatted + */ protected void addCharactersToCleanStringDecode(String cleanString){ logger.debug("Formatting output string for decoding"); @@ -313,7 +413,11 @@ public class PolybiusSquare{ outputString = fullOutput.toString(); logger.debug("Formatted output '{}'", outputString); } - //Encodes inputString using the Playfair cipher and stores the result in outputString + /** + * Encodes the input string using the Polybius cipher and stores the result in the output string. + * + * @throws InvalidInputException if the input string is invalid + */ protected void encode() throws InvalidInputException{ logger.debug("Encoding"); @@ -337,7 +441,11 @@ public class PolybiusSquare{ //Add other characters to the output string addCharactersToCleanStringEncode(output.toString()); } - //Decodes inputString using the Playfair cipher and stores the result in outputString + /** + * Decodes the input string using the Polybius cipher and stores the result in the output string. + * + * @throws InvalidInputException if the input string is invalid + */ protected void decode(){ logger.debug("Decoding"); @@ -363,7 +471,12 @@ public class PolybiusSquare{ addCharactersToCleanStringDecode(output.toString()); } - //Constructors + //?Constructors + /** + * Constructs a PolybiusSquare cipher instance with default settings. + * + * @throws InvalidCharacterException if default characters are invalid + */ public PolybiusSquare() throws InvalidCharacterException{ reset(); setReplaced('J'); @@ -371,6 +484,13 @@ public class PolybiusSquare{ preserveWhitespace = false; preserveSymbols = false; } + /** + * Constructs a PolybiusSquare cipher instance with specified settings. + * + * @param preserveWhitespace whether to preserve whitespace + * @param preserveSymbols whether to preserve symbols + * @throws InvalidCharacterException if default characters are invalid + */ public PolybiusSquare(boolean preserveWhitespace, boolean preserveSymbols) throws InvalidCharacterException{ reset(); setReplaced('J'); @@ -378,6 +498,15 @@ public class PolybiusSquare{ this.preserveWhitespace = preserveWhitespace; this.preserveSymbols = preserveSymbols; } + /** + * Constructs a PolybiusSquare cipher instance with specified settings and characters. + * + * @param preserveWhitespace whether to preserve whitespace + * @param preserveSymbols whether to preserve symbols + * @param replaced the character to be replaced + * @param replacer the character to replace the replaced character + * @throws InvalidCharacterException if any character is invalid + */ public PolybiusSquare(boolean preserveWhitespace, boolean preserveSymbols, char replaced, char replacer) throws InvalidCharacterException{ reset(); setReplaced(replaced); @@ -386,10 +515,26 @@ public class PolybiusSquare{ this.preserveSymbols = preserveSymbols; } - //Sets the keyword and inputString and encodes the message + /** + * Sets the keyword and input string and encodes the message. + * + * @param inputString the message to encode + * @return the encoded message + * @throws InvalidCharacterException if any character is invalid + * @throws InvalidInputException if the input string is invalid + */ public String encode(String inputString) throws InvalidCharacterException, InvalidInputException{ return encode("", inputString); } + /** + * Sets the keyword and input string and encodes the message. + * + * @param keyword the keyword for the cipher + * @param inputString the message to encode + * @return the encoded message + * @throws InvalidCharacterException if any character is invalid + * @throws InvalidInputException if the input string is invalid + */ public String encode(String keyword, String inputString) throws InvalidCharacterException, InvalidInputException{ reset(); setKeyword(keyword); @@ -397,10 +542,26 @@ public class PolybiusSquare{ encode(); return outputString; } - //Sets the keyword and inputString and decodes the message + /** + * Sets the keyword and input string and decodes the message. + * + * @param inputString the encoded message to decode + * @return the decoded message + * @throws InvalidCharacterException if any character is invalid + * @throws InvalidInputException if the input string is invalid + */ public String decode(String inputString) throws InvalidCharacterException, InvalidInputException{ return decode("", inputString); } + /** + * Sets the keyword and input string and decodes the message. + * + * @param keyword the keyword for the cipher + * @param inputString the encoded message to decode + * @return the decoded message + * @throws InvalidCharacterException if any character is invalid + * @throws InvalidInputException if the input string is invalid + */ public String decode(String keyword, String inputString) throws InvalidCharacterException, InvalidInputException{ reset(); setKeyword(keyword); @@ -409,7 +570,9 @@ public class PolybiusSquare{ return outputString; } - //Makes sure all variables are empty + /** + * Resets all variables to their default values. + */ public void reset(){ logger.debug("Resetting fields"); @@ -419,22 +582,52 @@ public class PolybiusSquare{ keyword = ""; } - //Getters + //?Getters + /** + * Returns the replaced character. + * + * @return the replaced character + */ public char getReplaced(){ return replaced; } + /** + * Returns the replacer character. + * + * @return the replacer character + */ public char getReplacer(){ return replacer; } + /** + * Returns the keyword used in the cipher. + * + * @return the keyword + */ public String getKeyword(){ return keyword; } + /** + * Returns the input string that was set for encoding/decoding. + * + * @return the input string + */ public String getInputString(){ return inputString; } + /** + * Returns the output string after encoding/decoding. + * + * @return the output string + */ public String getOutputString(){ return outputString; } + /** + * Returns a string representation of the grid. + * + * @return the grid as a string + */ public String getGrid(){ logger.debug("Creating string from grid"); diff --git a/src/main/java/com/mattrixwv/cipherstream/polysubstitution/RailFence.java b/src/main/java/com/mattrixwv/cipherstream/polysubstitution/RailFence.java index 5e6d03d..41a7b0d 100644 --- a/src/main/java/com/mattrixwv/cipherstream/polysubstitution/RailFence.java +++ b/src/main/java/com/mattrixwv/cipherstream/polysubstitution/RailFence.java @@ -1,7 +1,23 @@ //CipherStreamJava/src/main/java/com/mattrixwv/cipherstream/polysubstitution/RailFence.java //Mattrixwv // Created: 03-21-22 -//Modified: 05-04-23 +//Modified: 08-11-24 +/* + Copyright (C) 2024 Mattrixwv + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ package com.mattrixwv.cipherstream.polysubstitution; @@ -14,19 +30,35 @@ import com.mattrixwv.cipherstream.exceptions.InvalidBaseException; import com.mattrixwv.cipherstream.exceptions.InvalidInputException; +/** + * Represents the Rail Fence cipher encryption and decryption. + * The Rail Fence cipher is a form of transposition cipher that writes the message in a zigzag pattern + * across multiple "rails" and then reads it off row by row to encode or decode the message. + */ public class RailFence{ private static final Logger logger = LoggerFactory.getLogger(RailFence.class); - //Fields - protected String inputString; //The message that needs to be encoded/decoded - protected String outputString; //The encoded/decoded message - protected StringBuilder[] fence; //The fence used for encoding/decoding - //Settings - protected boolean preserveCapitals; //Persist capitals in the output string - protected boolean preserveWhitespace; //Persist whitespace in the output string - protected boolean preserveSymbols; //Persist symbols in the output string + //?Fields + /** The message that needs to be encoded/decoded */ + protected String inputString; + /** The encoded/decoded message */ + protected String outputString; + /** The fence used for encoding/decoding */ + protected StringBuilder[] fence; + //?Settings + /** Persist capitals in the output string */ + protected boolean preserveCapitals; + /** Persist whitespace in the output string */ + protected boolean preserveWhitespace; + /** Persist symbols in the output string */ + protected boolean preserveSymbols; - //Strips invalid characters from the string that needs encoded/decoded + /** + * Strips invalid characters from the string that needs to be encoded/decoded. + * + * @param inputString the input string to be cleaned + * @throws InvalidInputException if the input string is null or invalid + */ protected void setInputString(String inputString) throws InvalidInputException{ //Ensure the input string isn't null if(inputString == null){ @@ -61,7 +93,12 @@ public class RailFence{ throw new InvalidInputException("Input must contain at least 1 letter"); } } - //Ensures the number of rails is valid and sets up the fence + /** + * Ensures the number of rails is valid and sets up the fence. + * + * @param numRails the number of rails to be used + * @throws InvalidBaseException if the number of rails is less than 2 + */ protected void setNumRails(int numRails) throws InvalidBaseException{ if(numRails < 2){ throw new InvalidBaseException("You must use at least 2 rails"); @@ -74,13 +111,21 @@ public class RailFence{ fence[cnt] = new StringBuilder(); } } - //Strip the inputString of all non-letter characters + /** + * Strips the input string of all non-letter characters. + * + * @return the cleaned input string + */ protected String getCleanInputString(){ logger.debug("Getting input string for encoding"); return inputString.replaceAll("[^a-zA-Z]", ""); } - //Ensures capitals, lowercase, and symbols are displayed in the output string + /** + * Ensures capitals, lowercase, and symbols are displayed in the output string. + * + * @param outputString the encoded/decoded output string to be formatted + */ protected void formatOutput(String outputString){ logger.debug("Formatting output string"); @@ -109,7 +154,11 @@ public class RailFence{ this.outputString = output.toString(); logger.debug("Formatted output '{}'", this.outputString); } - //Returns the decoded string found in the fence after all characters are placed correctly + /** + * Returns the decoded string found in the fence after all characters are placed correctly. + * + * @return the decoded string + */ protected String getDecodedStringFromFence(){ logger.debug("Getting decoded string from the fence"); @@ -161,7 +210,9 @@ public class RailFence{ logger.debug("Fence output '{}'", output); return output.toString(); } - //Encodes inputString using the RailFence cipher and stores the result in outputString + /** + * Encodes the input string using the Rail Fence cipher and stores the result in the output string. + */ protected void encode(){ logger.debug("Encoding"); @@ -204,7 +255,9 @@ public class RailFence{ //Format the output formatOutput(output.toString()); } - //Decodes inputString using the RailFence cipher and stores the result in outputString + /** + * Decodes the input string using the Rail Fence cipher and stores the result in the output string. + */ protected void decode(){ logger.debug("Decoding"); @@ -256,13 +309,23 @@ public class RailFence{ formatOutput(output); } - //Constructor + //?Constructor + /** + * Constructs a RailFence cipher instance with default settings. + */ public RailFence(){ preserveCapitals = false; preserveWhitespace = false; preserveSymbols = false; reset(); } + /** + * Constructs a RailFence cipher instance with specified settings. + * + * @param preserveCapitals whether to preserve uppercase letters + * @param preserveWhitespace whether to preserve whitespace + * @param preserveSymbols whether to preserve symbols + */ public RailFence(boolean preserveCapitals, boolean preserveWhitespace, boolean preserveSymbols){ this.preserveCapitals = preserveCapitals; this.preserveWhitespace = preserveWhitespace; @@ -270,7 +333,15 @@ public class RailFence{ reset(); } - //Encodes inputString using a Rail Fence of length numRails and returns the result + /** + * Encodes the input string using a Rail Fence of the specified number of rails and returns the result. + * + * @param numRails the number of rails to use + * @param inputString the message to encode + * @return the encoded message + * @throws InvalidBaseException if the number of rails is invalid + * @throws InvalidInputException if the input string is invalid + */ public String encode(int numRails, String inputString) throws InvalidBaseException, InvalidInputException{ //Set the parameters setNumRails(numRails); @@ -280,7 +351,15 @@ public class RailFence{ encode(); return outputString; } - //Decodes inputString using a Rail Fence of length numRails and returns the result + /** + * Decodes the input string using a Rail Fence of the specified number of rails and returns the result. + * + * @param numRails the number of rails to use + * @param inputString the encoded message to decode + * @return the decoded message + * @throws InvalidBaseException if the number of rails is invalid + * @throws InvalidInputException if the input string is invalid + */ public String decode(int numRails, String inputString) throws InvalidBaseException, InvalidInputException{ //Set the parameters setNumRails(numRails); @@ -291,7 +370,9 @@ public class RailFence{ return outputString; } - //Makes sure all variables are empty + /** + * Resets all variables to their default values. + */ public void reset(){ logger.debug("Resetting fields"); @@ -300,13 +381,28 @@ public class RailFence{ fence = null; } - //Getters + //?Getters + /** + * Returns the input string that was set for encoding/decoding. + * + * @return the input string + */ public String getInputString(){ return inputString; } + /** + * Returns the output string after encoding/decoding. + * + * @return the output string + */ public String getOutputString(){ return outputString; } + /** + * Returns the number of rails used in the Rail Fence cipher. + * + * @return the number of rails + */ public int getNumRails(){ return fence.length; } diff --git a/src/main/java/com/mattrixwv/cipherstream/polysubstitution/Trifid.java b/src/main/java/com/mattrixwv/cipherstream/polysubstitution/Trifid.java index 042682b..29439bc 100644 --- a/src/main/java/com/mattrixwv/cipherstream/polysubstitution/Trifid.java +++ b/src/main/java/com/mattrixwv/cipherstream/polysubstitution/Trifid.java @@ -1,7 +1,23 @@ //CipherStreamJava/src/main/java/com/mattrixwv/cipherstream/polysubstitution/Trifid.java //Mattrixwv // Created: 03-03-22 -//Modified: 04-19-24 +//Modified: 08-11-24 +/* + Copyright (C) 2024 Mattrixwv + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ package com.mattrixwv.cipherstream.polysubstitution; @@ -17,46 +33,92 @@ import com.mattrixwv.cipherstream.exceptions.InvalidInputException; import com.mattrixwv.cipherstream.exceptions.InvalidKeywordException; +/** + * The {@code Trifid} class implements the Trifid cipher, a polyalphabetic substitution cipher + * that uses a 3x3x3 grid to encode and decode messages. + */ public class Trifid{ private static final Logger logger = LoggerFactory.getLogger(Trifid.class); - //A class representing the location of a character in the grid + /** A class representing the location of a character in the grid */ protected class CharLocation{ + /** The x location in the grid */ protected int x; + /** The y location in the grid */ protected int y; + /** The z location in the grid */ protected int z; + /** + * Constructs a CharLocation with the specified x and y coordinates. + * + * @param x the x-coordinate of the character's location + * @param y the y-coordinate of the character's location + * @param z the z-coordinate of the character's location + */ public CharLocation(int x, int y, int z){ this.x = x; this.y = y; this.z = z; } + /** + * Returns the x-coordinate of the character's location. + * + * @return the x-coordinate + */ public int getX(){ return x; } + /** + * Returns the y-coordinate of the character's location. + * + * @return the y-coordinate + */ public int getY(){ return y; } + /** + * Returns the z-coordinate of the character's location. + * + * @return the z-coordinate + */ public int getZ(){ return z; } + /** + * Prints out the location in a human readable format + */ public String toString(){ return "[" + (z + 1) + ", " + (x + 1) + ", " + (y + 1) + "]"; } } - //Fields - protected String inputString; //The message that needs to be encoded/decoded - protected String outputString; //The encoded/decoded message - protected String keyword; //The keyword used to create the grid - protected int groupSize; //The size of the groups used to break up the input - protected char[][][] grid; //The grid used to encode/decode the message - protected char fillIn; //The character added to the alphabet to meet the 27 character requirement - //Settings - protected boolean preserveCapitals; //Persist capitals in the output string - protected boolean preserveWhitespace; //Persist whitespace in the output string - protected boolean preserveSymbols; //Persist symbols in the output string + //?Fields + /** The message that needs to be encoded/decoded */ + protected String inputString; + /** The encoded/decoded message */ + protected String outputString; + /** The keyword used to create the grid */ + protected String keyword; + /** The size of the groups used to break up the input */ + protected int groupSize; + /** The grid used to encode/decode the message */ + protected char[][][] grid; + /** The character added to the alphabet to meet the 27 character requirement */ + protected char fillIn; + //?Settings + /** Persist capitals in the output string */ + protected boolean preserveCapitals; + /** Persist whitespace in the output string */ + protected boolean preserveWhitespace; + /** Persist symbols in the output string */ + protected boolean preserveSymbols; - //Makes sure the fillIn is a valid character + /** + * Sets the fill-in character used to complete the 27-character requirement for the grid. + * + * @param fillIn the fill-in character + * @throws InvalidCharacterException if the fill-in character is not a printable non-letter character + */ protected void setFillIn(char fillIn) throws InvalidCharacterException{ //Make sure the character is a printing character if((fillIn < ' ') || (fillIn > '~')){ @@ -72,7 +134,13 @@ public class Trifid{ //Save the fillIn character this.fillIn = fillIn; } - //Strips invalid characters from the keyword and creates the grid + /** + * Processes the keyword to generate the 3D grid. The keyword is sanitized to include + * only capital letters and the fill-in character. + * + * @param keyword the keyword used to create the grid + * @throws InvalidKeywordException if the keyword is invalid + */ protected void setKeyword(String keyword) throws InvalidKeywordException{ //Ensure the keyword isn't null if(keyword == null){ @@ -104,7 +172,9 @@ public class Trifid{ //Create the grid from the sanitized keyword createGrid(); } - //Creates the grid from the keyword + /** + * Creates the 3D grid from the processed keyword. + */ protected void createGrid(){ logger.debug("Creating grid from keyword"); @@ -120,7 +190,12 @@ public class Trifid{ logger.debug("Completed grid\n{}", getGrid()); } - //Ensures groupSize constraints + /** + * Sets the group size used for encoding and decoding the input string. + * + * @param groupSize the group size + * @throws InvalidBaseException if the group size is less than or equal to zero + */ protected void setGroupSize(int groupSize) throws InvalidBaseException{ if(groupSize <= 0){ throw new InvalidBaseException("Group size must be > 0"); @@ -130,7 +205,13 @@ public class Trifid{ this.groupSize = groupSize; } - //Ensures inputString constraints + /** + * Prepares the input string for encoding or decoding by applying preservation settings + * and validating the input. + * + * @param inputString the input string to be processed + * @throws InvalidInputException if the input string is invalid + */ protected void setInputString(String inputString) throws InvalidInputException{ //Ensure the input string isn't null if(inputString == null){ @@ -165,12 +246,22 @@ public class Trifid{ throw new InvalidInputException("Input must contain at least 1 letter"); } } - //Returns the inputString with only letters + /** + * Returns the input string with only valid letters and fill-in characters. + * + * @return the cleaned input string + */ protected String getCleanInputString(){ logger.debug("Cleaning input string for encoding"); return inputString.toUpperCase().replaceAll("[^A-Z" + fillIn + "]", ""); } - //Returns the location of the given character in the grid + /** + * Finds the location of a given character in the 3D grid. + * + * @param letter the character to find + * @return the location of the character + * @throws InvalidCharacterException if the character is not found in the grid + */ protected CharLocation findChar(char letter) throws InvalidCharacterException{ logger.debug("Finding character {} in grid", letter); @@ -189,7 +280,13 @@ public class Trifid{ //If it was not found something went wrong throw new InvalidCharacterException("The character '" + letter + "' was not found in the grid"); } - //Return the character from the location provided + /** + * Retrieves the character at the specified location in the 3D grid. + * + * @param location the location of the character + * @return the character at the specified location + * @throws InvalidCharacterException if the location is out of bounds + */ protected char getChar(CharLocation location) throws InvalidCharacterException{ if(location.getX() > 2){ throw new InvalidCharacterException("x cannot be larget than 2"); @@ -205,7 +302,11 @@ public class Trifid{ return grid[location.getZ()][location.getX()][location.getY()]; } - //Adds all non-letter characters back to the output string + /** + * Formats the output string according to the preservation settings. + * + * @param outputString the output string to format + */ protected void formatOutput(String outputString){ logger.debug("Formatting output"); @@ -242,7 +343,11 @@ public class Trifid{ this.outputString = output.toString(); logger.debug("Formatted output '{}'", this.outputString); } - //Encodes inputString using a polybius square and stores the result in outputString + /** + * Encodes the input string using the Trifid cipher. + * + * @throws InvalidCharacterException if an invalid character is encountered + */ protected void encode() throws InvalidCharacterException{ logger.debug("Encoding"); @@ -308,7 +413,11 @@ public class Trifid{ //Format the output formatOutput(output.toString()); } - //Decodes inputString using a polybius square and stores the result in outputString + /** + * Decodes the input string using the Trifid cipher. + * + * @throws InvalidCharacterException if an invalid character is encountered + */ protected void decode() throws InvalidCharacterException{ logger.debug("Decoding"); @@ -380,7 +489,10 @@ public class Trifid{ } - //Constructor + //?Constructor + /** + * Constructs a Trifid object with default settings. + */ public Trifid() throws InvalidCharacterException{ preserveCapitals = false; preserveWhitespace = false; @@ -388,6 +500,13 @@ public class Trifid{ setFillIn('+'); reset(); } + /** + * Constructs a Trifid object with default settings. + * + * @param preserveCapitals whether to preserve capital letters + * @param preserveWhitespace whether to preserve whitespace + * @param preserveSymbols whether to preserve symbols + */ public Trifid(boolean preserveCapitals, boolean preserveWhitespace, boolean preserveSymbols) throws InvalidCharacterException{ this.preserveCapitals = preserveCapitals; this.preserveWhitespace = preserveWhitespace; @@ -395,6 +514,15 @@ public class Trifid{ setFillIn('+'); reset(); } + /** + * Constructs a Trifid object with default settings. + * + * @param preserveCapitals whether to preserve capital letters + * @param preserveWhitespace whether to preserve whitespace + * @param preserveSymbols whether to preserve symbols + * @param fillIn the character to use for fill-in characters + * @throws InvalidCharacterException if the fill-in character is invalid + */ public Trifid(boolean preserveCapitals, boolean preserveWhitespace, boolean preserveSymbols, char fillIn) throws InvalidCharacterException{ this.preserveCapitals = preserveCapitals; this.preserveWhitespace = preserveWhitespace; @@ -403,10 +531,32 @@ public class Trifid{ reset(); } - //Encodes inputString using keyword and groupSize and returns the result + /** + * Encodes the specified input string using the provided keyword and group size. + * + * @param keyword the keyword used for encoding + * @param inputString the input string to encode + * @return the encoded string + * @throws InvalidBaseException if the group size is invalid + * @throws InvalidKeywordException if the keyword is invalid + * @throws InvalidInputException if the input string is invalid + * @throws InvalidCharacterException if an invalid character is encountered + */ public String encode(String keyword, String inputString) throws InvalidBaseException, InvalidKeywordException, InvalidInputException, InvalidCharacterException{ return encode(keyword, inputString.length(), inputString); } + /** + * Encodes the specified input string using the provided keyword and group size. + * + * @param keyword the keyword used for encoding + * @param groupSize the size of groups + * @param inputString the input string to encode + * @return the encoded string + * @throws InvalidBaseException if the group size is invalid + * @throws InvalidKeywordException if the keyword is invalid + * @throws InvalidInputException if the input string is invalid + * @throws InvalidCharacterException if an invalid character is encountered + */ public String encode(String keyword, int groupSize, String inputString) throws InvalidBaseException, InvalidKeywordException, InvalidInputException, InvalidCharacterException{ //Set the parameters reset(); @@ -418,10 +568,32 @@ public class Trifid{ encode(); return outputString; } - //Decodes inputString using keyword and groupSize and returns the result + /** + * Decodes the specified input string using the provided keyword and group size. + * + * @param keyword the keyword used for decoding + * @param inputString the input string to decode + * @return the decoded string + * @throws InvalidBaseException if the group size is invalid + * @throws InvalidKeywordException if the keyword is invalid + * @throws InvalidInputException if the input string is invalid + * @throws InvalidCharacterException if an invalid character is encountered + */ public String decode(String keyword, String inputString) throws InvalidBaseException, InvalidKeywordException, InvalidInputException, InvalidCharacterException{ return decode(keyword, inputString.length(), inputString); } + /** + * Decodes the specified input string using the provided keyword and group size. + * + * @param keyword the keyword used for decoding + * @param groupSize the size of groups + * @param inputString the input string to decode + * @return the decoded string + * @throws InvalidBaseException if the group size is invalid + * @throws InvalidKeywordException if the keyword is invalid + * @throws InvalidInputException if the input string is invalid + * @throws InvalidCharacterException if an invalid character is encountered + */ public String decode(String keyword, int groupSize, String inputString) throws InvalidBaseException, InvalidKeywordException, InvalidInputException, InvalidCharacterException{ //Set the parameters reset(); @@ -434,7 +606,9 @@ public class Trifid{ return outputString; } - //Makes sure all variables are empty + /** + * Resets all internal variables to their default values. + */ public void reset(){ logger.debug("Resetting fields"); @@ -445,22 +619,52 @@ public class Trifid{ grid = new char[3][3][3]; } - //Getters + //?Getters + /** + * Returns the current input string. + * + * @return the input string + */ public String getInputString(){ return inputString; } + /** + * Returns the current output string. + * + * @return the output string + */ public String getOutputString(){ return outputString; } + /** + * Returns the current keyword. + * + * @return the keyword + */ public String getKeyword(){ return keyword; } + /** + * Returns the current group size. + * + * @return the group size + */ public int getGroupSize(){ return groupSize; } + /** + * Returns the current fill-in character. + * + * @return the fill-in character + */ public char getFillIn(){ return fillIn; } + /** + * Returns a string representation of the 3D grid. + * + * @return the grid as a string + */ public String getGrid(){ logger.debug("Creating string from grid");