In: Computer Science
P-3.40 Implement a class, SubstitutionCipher, with a constructor that takes a string with the 26 uppercase letters in an arbitrary order and uses that as the encoder for a cipher (that is, A is mapped to the first character of the parameter, B is mapped to the second, and so on.) You should derive the decoding map from the forward version.
P-3.41 Redesign the CaesarCipher class as a subclass of the SubstitutionCipher from the previous problem.
P-3.42 Design a RandomCipher class as a subclass of the SubstitutionCipher from Exercise P-3.40, so that each instance of the class relies on a random permutation of letters for its mapping.
Part A
public class SubstitutionCipher {
   static final int MAX = 26;
   protected char[] encoder; // Encryption array
   protected char[] decoder; // Decryption array
  
   /**
   * Constructor
   */
   public SubstitutionCipher() {
       this.encoder = new char[MAX]; // Encryption array
       this.decoder = new char[MAX]; // Decryption array
   }
  
   /**
   * Sets the encoder string and generates the decoder
   * @param encoderString
   */
   public void setEncoder (String encoderString) {
       this.encoder = encoderString.toCharArray();
      
       // Generate decoder
       for (int i = 0; i < MAX; i++) {
           char ch = (char)('A' + i);   // For each iteration ch will hold a value from A - Z
           // Find ch in the encoderString
           int pos = encoderString.indexOf(ch);
           // If pos is not found display error
           if (pos == -1) {
               System.out.println("Invalid encoder string");
               System.exit(1);
           }
          
           // If index is found
           // get the char at the pos in the original alphabet order
           // assign the char to decoder[i]
           this.decoder[i] = (char)('A' + pos);
       }
   }
  
   /**
   * Returns String representing encrypted message.
   */
   public String encrypt(String message) {
       return transform(message, encoder); // use encoder array
   }
   /**
   * Returns decrypted message given encrypted secret.
   */
   public String decrypt(String secret) {
       return transform(secret, decoder); // use decoder array
   }
   /**
   * Returns transformation of original String using given code.
   */
   private String transform(String original, char[] code) {
       char[] msg = original.toCharArray();
       for (int k = 0; k < msg.length; k++)
           if (Character.isUpperCase(msg[k])) { // we have a letter to change
               int j = msg[k] - 'A'; // will be value from 0 to 25
               msg[k] = code[j]; // replace the character
           }
       return new String(msg);
   }
   public static void main(String[] args) {
      
       String encoderString = new String("SIEXHVGFUDJTRZNPCLQBKAYWOM");
      
       // Create SubstitutionCipher object
       SubstitutionCipher subCipher = new SubstitutionCipher();
       // Set encoder
       subCipher.setEncoder(encoderString);
      
       System.out.println("Encryption code = " + new String(subCipher.encoder));
       System.out.println("Decryption code = " + new String(subCipher.decoder));
       String message = "THE EAGLE IS IN PLAY; MEET AT JOE'S.";
       String coded = subCipher.encrypt(message);
       System.out.println("Secret: " + coded);
       String answer = subCipher.decrypt(coded);
       System.out.println("Message: " + answer);
   }
}
PART B
public class CaesarCipherRedesign extends SubstitutionCipher {
   /**
   * Constructor that initializes the encryption and decryption arrays
   */
   public CaesarCipherRedesign(int rotation) {
       // For upper case
       for (int k = 0; k < 26; k++) {
           encoder[k] = (char) ('A' + (k + rotation) % super.MAX);
       }
   }
   public static void main(String[] args) {
       CaesarCipher cipher = new CaesarCipher(1);
       System.out.println("Encryption code = " + new String(cipher.encoder));
       System.out.println("Decryption code = " + new String(cipher.decoder));
       String message = "THE EAGLE IS IN PLAY; MEET AT JOE'S.";
       String coded = cipher.encrypt(message);
       System.out.println("Secret: " + coded);
       String answer = cipher.decrypt(coded);
       System.out.println("Message: " + answer); // should be plain text again
   }
}
I hope this answer helps you please upvote if both the parts helped you!!!!