import java.util.*; import java.io.*; // Represents a classical cipher that is able to encode a plaintext into a ciphertext, and // decode a ciphertext into a plaintext. Also capable of encoding and decoding entire files public abstract class Cipher { // The minimum character able to be encoded by any cipher public static final int MIN_CHAR = (int)(' '); // The maximum character able to be encoded by any cipher public static final int MAX_CHAR = (int)('}'); // The total number of characters able to be encoded by any cipher (aka. the encodable range) public static final int TOTAL_CHARS = MAX_CHAR - MIN_CHAR + 1; // Pre: Throws a FileNotFoundException if a file with the provided 'fileName' doesn't exist // Post: Applies this Cipher's encryption scheme to the file with the given 'fileName', creating // a new file to store the results. public void encryptFile(String fileName) throws FileNotFoundException { fileHelper(fileName, true, "-encoded"); } // Pre: Throws a FileNotFoundException if a file with the provided 'fileName' doesn't exist // Post: Applies this Cipher's decryption scheme (reversing a single round of encryption if applied) // to the file with the given 'fileName', creating a new file to store the results. public void decryptFile(String fileName) throws FileNotFoundException { fileHelper(fileName, false, "-decoded"); } // Pre: Throws a FileNotFoundException if a file with the provided 'fileName' doesn't exist // Post: Reads from an input file with 'fileName', either encrypting or decrypting depending on 'encode', // printing the results to a new file with 'suffix' appended to the input file's name private void fileHelper(String fileName, boolean encode, String suffix) throws FileNotFoundException{ Scanner sc = new Scanner(new File(fileName)); String out = fileName.split("\\.txt")[0] + suffix + ".txt"; PrintStream ps = new PrintStream(out); while(sc.hasNextLine()) { String line = sc.nextLine(); ps.println(encode ? encrypt(line) : decrypt(line)); } } // Post: Returns the result of applying this Cipher's encryption scheme to 'input' public abstract String encrypt(String input); // Post: Returns the result of applying this Cipher's decryption scheme to 'input' public abstract String decrypt(String input); }