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!!!!