· 5 years ago · Nov 23, 2019, 10:16 AM
1import java.util.Scanner;
2
3public class CaesarCipher {
4
5 static Scanner scan = new Scanner(System.in);
6
7 public static void main(String args[]) {
8
9 System.out.println("This program demonstrates different functions of a Caesar cipher. "
10 + "\nIt can can encrypt, decrypt, and determine possible encryption values of a cipher."
11 + "\nPlease only enter input in capital letters. ");
12
13 System.out.print("\n\nPlease enter the message you would like to encrypt: ");
14 String originalMessage = scan.nextLine();
15
16 System.out.print("Please enter your secret key: ");
17 int secretKey = scan.nextInt();
18
19 encryptMessage(originalMessage, secretKey);
20
21 scan.nextLine();
22
23 System.out.print("\n\nPlease enter the message you would like to decrypt: ");
24 String userEncryptedMessage = scan.nextLine();
25
26 System.out.print("Please enter your secret key: ");
27 secretKey = scan.nextInt();
28
29 decryptMessage(userEncryptedMessage, secretKey);
30
31 scan.nextLine();
32
33 System.out.print("\n\nPlease enter the message you would like to identify: ");
34 String encryptedMessage = scan.nextLine();
35
36 System.out.print("Please enter the letter you would like to identify: ");
37 char letter = scan.next().charAt(0);
38
39 System.out.print(
40 "Please enter your identifier number (the number of times the given letter appeared in the original message): ");
41 int numberOfTimes = scan.nextInt();
42
43 identifyKeys(encryptedMessage, letter, numberOfTimes);
44
45 }
46
47 public static String encryptMessage(String originalMessage, int secretKey) {
48 String encryptedMessage = "";
49
50 /*
51 * This method includes a for loop that iterates for the amount of letters in
52 * the user's string. It takes the user's input message and makes sure it is in
53 * all capitalized letters by comparing ASCII values. This is done to make sure
54 * that encryption is only done on capitalized letters, but more importantly, it
55 * is not done on text like spaces and punctuation. It then creates a char for
56 * the letter at the index, and encrypts it by adding the secret key and
57 * converting the letter to its alphabet numerical value. The letter is
58 * converted back into its ASCII format, and added to the encrypted message
59 * string. This is done to account for wraparound, i.e. when a word wraps around
60 * the other side of the alphabet.
61 */
62
63 for (int i = 0; i < originalMessage.length(); i++) {
64 if (originalMessage.charAt(i) > 64 && originalMessage.charAt(i) < 91) {
65 char ch = (char) ((int) (originalMessage.charAt(i) + (secretKey - 65)) % 26 + 65);
66 encryptedMessage += ch;
67 } else {
68 encryptedMessage += originalMessage.charAt(i);
69 }
70 }
71 // Prints user encrypted message
72 System.out.println("\nThe encrypted message is: " + encryptedMessage);
73
74 return encryptedMessage;
75 }
76
77 public static String decryptMessage(String userEncryptedMessage, int secretKey) {
78 String decryptedMessage = "";
79
80 /*
81 * This method is the same as the encryptMessage method, however it works in
82 * reverse. It simply subtracts the secret key in order to decode, instead of
83 * adding it.
84 */
85
86 for (int i = 0; i < userEncryptedMessage.length(); i++) {
87 if (userEncryptedMessage.charAt(i) > 64 && userEncryptedMessage.charAt(i) < 91) {
88 char ch = (char) ((int) (userEncryptedMessage.charAt(i) - (secretKey - 65)) % 26 + 65);
89 decryptedMessage += ch;
90 } else {
91 decryptedMessage += userEncryptedMessage.charAt(i);
92 }
93 }
94
95 // Prints user encrypted message
96 System.out.println("\nThe decrypted message is: " + decryptedMessage);
97 return decryptedMessage;
98 }
99
100 public static void identifyKeys(String encryptedMessage, char letter, int numberOfTimes) {
101 int frequency = 0;
102 String possibleCodes = "";
103 int letterToAlphabet = (((int) letter - 65) % 26);
104
105 // Outer loop iterates the index verification 25 times, for 25 possible shift values
106 for (int i = 1; i < 26; i++) {
107
108 /*
109 * Inner loop iterates to the length of the user's encrypted message. This loop
110 * converts each letter into a number corresponding to it's letter in the
111 * alphabet (starting from 0). It then checks to see if this value matches the
112 * value of the user's letter. If this statement is true, it increments
113 * frequency by 1. This is then used to test against the user's number - the
114 * number of times the given letter appeared in the original message If the
115 * frequency matches the user's number, 'i' (the number of the current iteration
116 * that the outer loop is on) is added as a possible code.
117 */
118
119 for (int j = 0; j < encryptedMessage.length(); j++) {
120
121 if ((((int) encryptedMessage.charAt(j) + i - 65) % 26) == letterToAlphabet) {
122 frequency++;
123
124 }
125
126 //
127 if (frequency == numberOfTimes) {
128
129 // Check to ensure there are no trailing commas if only 1 cipher code is
130 // possible
131 if (possibleCodes.length() != 0) {
132 possibleCodes += ", ";
133 }
134 possibleCodes += (26 - i);
135
136 frequency = 0;
137 }
138
139 }
140 frequency = 0;
141
142 }
143
144 /*
145 * Print possible values in the order they were found in. This is usually
146 * reverse chronological. To make the program print in chronological order, the
147 * method's if statement has to be made to decrement from 26, instead of
148 * increment from 1
149 */
150
151 System.out.println("\nThe possible values are: " + possibleCodes + ".");
152 }
153
154}