Added Javadoc comments to the classes

This commit is contained in:
2024-08-11 23:48:02 -04:00
parent b16956b184
commit c10df8e5df
29 changed files with 3270 additions and 431 deletions

165
LICENSE Normal file
View File

@@ -0,0 +1,165 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
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.

View File

@@ -26,7 +26,7 @@
<groupId>com.mattrixwv</groupId>
<artifactId>cipher-stream-java</artifactId>
<version>1.3.6-SNAPSHOT</version>
<version>1.3.6</version>
<name>CipherStreamJava</name>
<description>A library to encrypt and decrypt simple ciphers</description>

View File

@@ -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 <https://www.gnu.org/licenses/>.
*/
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.
*
* <p>
* The cipher involves two main steps:
* </p>
* <ol>
* <li>Encoding/decoding with a Polybius square (LargePolybiusSquare)</li>
* <li>Encoding/decoding with a columnar transposition cipher (Columnar)</li>
* </ol>
*/
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");

View File

@@ -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 <https://www.gnu.org/licenses/>.
*/
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.
*
* <p>
* The cipher involves two main steps:
* </p>
* <ol>
* <li>Encoding/decoding with a Polybius square (PolybiusSquare)</li>
* <li>Encoding/decoding with a columnar transposition cipher (Columnar)</li>
* </ol>
*/
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");

View File

@@ -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 <https://www.gnu.org/licenses/>.
*/
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);
}

View File

@@ -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 <https://www.gnu.org/licenses/>.
*/
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);
}

View File

@@ -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 <https://www.gnu.org/licenses/>.
*/
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);
}

View File

@@ -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 <https://www.gnu.org/licenses/>.
*/
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);
}

View File

@@ -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 <https://www.gnu.org/licenses/>.
*/
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);
}

View File

@@ -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 <https://www.gnu.org/licenses/>.
*/
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.
*
* <p>
* The Affine cipher uses two keys:
* </p>
* <ul>
* <li><strong>Key1</strong>: The multiplicative key (must be relatively prime to 26)</li>
* <li><strong>Key2</strong>: The additive key</li>
* </ul>
*/
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");

View File

@@ -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 <https://www.gnu.org/licenses/>.
*/
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.
*
* <p>
* The Atbash cipher is symmetric, meaning that encoding and decoding are the same operation.
* </p>
*/
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");

View File

@@ -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 <https://www.gnu.org/licenses/>.
*/
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.
*
* <p>
* The Autokey cipher is symmetric, meaning that encoding and decoding are essentially the same process, but with a different key setup for decoding.
* </p>
*/
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();

View File

@@ -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 <https://www.gnu.org/licenses/>.
*/
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.
*
* <p>
* 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.
* </p>
*/
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<String> 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");

View File

@@ -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 <https://www.gnu.org/licenses/>.
*/
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.
*
* <p>
* 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.
* </p>
*/
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");

View File

@@ -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 <https://www.gnu.org/licenses/>.
*/
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.
*
* <p>
* The Beaufort cipher consists of three main steps:
* </p>
* <ul>
* <li>Atbash cipher for reversing the string</li>
* <li>Caesar cipher for shifting characters by a fixed amount</li>
* <li>Vigenère cipher for applying a keyword-based shift</li>
* </ul>
* 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:
* <ul>
* <li>Encodes the input string using the Atbash cipher</li>
* <li>Shifts the result by 1 using the Caesar cipher</li>
* <li>Applies the Vigenère cipher using the keyword</li>
* </ul>
*/
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");

View File

@@ -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 <https://www.gnu.org/licenses/>.
*/
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.
*
* <p>
* 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.
* </p>
*/
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");

View File

@@ -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 <https://www.gnu.org/licenses/>.
*/
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.
*
* <p>
* 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.
* </p>
*/
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()){

View File

@@ -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 <https://www.gnu.org/licenses/>.
*/
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.
*
* <p>
* 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.
* </p>
*/
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");

View File

@@ -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 <https://www.gnu.org/licenses/>.
*/
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.
*
* <p>
* 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.
* </p>
*/
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");

View File

@@ -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 <https://www.gnu.org/licenses/>.
*/
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.
*
* <p>
* 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.
* </p>
*/
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<Integer> 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<Integer> 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<Integer> getOffsets(){
return offset;
}
//Makes sure all variables are empty
/**
* Resets all fields to their default values.
*/
public void reset(){
logger.debug("Resetting fields");

View File

@@ -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 <https://www.gnu.org/licenses/>.
*/
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.
*
* <p>
* 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.
* </p>
*/
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");

View File

@@ -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 <https://www.gnu.org/licenses/>.
*/
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.
* <p>
* 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.
* </p>
*/
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<ArrayList<Character>> 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<ArrayList<Character>> 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<Integer> 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<Integer> 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<Integer> 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;
}

View File

@@ -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 <https://www.gnu.org/licenses/>.
*/
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.
* <p>
* 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.
* </p>
*/
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<ModMatrix> 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<ModMatrix> 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;
}

View File

@@ -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 <https://www.gnu.org/licenses/>.
*/
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);
}

View File

@@ -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 <https://www.gnu.org/licenses/>.
*/
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.
* <p>
* 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.
* </p>
*/
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<String, Character> 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<String, Character> 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.
* <p>
* This method converts the input string to uppercase, removes all non-alphanumeric characters, and stores the cleaned string.
* </p>
*
* @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.
* <p>
* This method ensures that the input string contains only valid Morse code characters (dots, dashes, and spaces).
* </p>
*
* @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.
* <p>
* This method converts each alphanumeric character in the input string to its Morse code representation and stores the result.
* </p>
*
* @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.
* <p>
* This method converts each Morse code sequence in the input string back to its corresponding alphanumeric character.
* </p>
*
* @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.
* <p>
* This method validates the input string, encodes it, and returns the Morse code representation.
* </p>
*
* @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.
* <p>
* This method validates the Morse code input, decodes it, and returns the plain text representation.
* </p>
*
* @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");

View File

@@ -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 <https://www.gnu.org/licenses/>.
*/
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");

View File

@@ -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 <https://www.gnu.org/licenses/>.
*/
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");

View File

@@ -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 <https://www.gnu.org/licenses/>.
*/
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;
}

View File

@@ -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 <https://www.gnu.org/licenses/>.
*/
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");