I am giving the user a menu to choose from, once I run my program and I use all choices it runs smoothly except for choice number 3 , it runs for only one time, after the first iterate , it immediately gives an error and stop.
Error :
Exception in thread “main” java.util.NoSuchElementException: No line found at java.base/java.util.Scanner.nextLine(Scanner.java:1651) at Encrypting_Decrypting.main(Encrypting_Decrypting.java:39)
I tried to handle the error by try,except . But the program still gives me an error : Input error: No line found Program stopped.
note that if you want to run it , you need to have :
encrypted.txt contains :
PK DM DHW HUTNDPUB LSUKPMNWCRJU CX BJH, QN FAXCN RN PU LPJDMR, NDHN PY, IT YS LKDQJLQJ WKH RUGHU RI WKH AMNNMRY SK NDM HAJDHIMN.
dictionary.txt contains:
if
he
had
anything
confidential
to
say
he
wrote
cipher
that is
so
changing
the
order
of
the
letters
of
the
alphabet
main function :
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
boolean keepRunning = true;
do {
try {
// Display the main menu
System.out.println("Choose an option:");
System.out.println("1. Encrypt");
System.out.println("2. Decrypt");
System.out.println("3. Cryptanalysis");
System.out.println("4. Exit");
System.out.print("Enter your choice (1/2/3/4): ");
// Ensure there's an integer input available
int choice = scanner.nextInt();
scanner.nextLine(); // Consume newline after nextInt()
while (!scanner.hasNextInt()) {
System.err.println("Invalid input. Please enter a number.");
choice = 5;
scanner.nextLine(); // Consume the invalid input
}
// Validate the choice
if (choice < 1 || choice > 4) {
System.out.println("Invalid choice. Please choose again.");
continue;
}
switch (choice) {
case 1:
System.out.print("Enter the name of the file to encrypt: ");
String filename = scanner.nextLine();
try {
// Read lines from the specified file
List<String> lines = Files.readAllLines(Paths.get(filename));
if (lines.size() < 1) {
System.out.println("File is empty or doesn't have a key.");
break;
}
String substitutionKey = lines.get(0).toUpperCase();
if (substitutionKey.length() != 26) {
System.out.println("Invalid key length. Key should be 26 characters long.");
break;
}
// Update the SUBSTITUTION constant with the new key
SUBSTITUTION = substitutionKey;
// Combine the remaining lines to form the plaintext
String plaintext = String.join("n", lines.subList(1, lines.size())).toUpperCase().trim();
String encrypted = encrypt(plaintext);
System.out.println("Encrypted: " + encrypted.toLowerCase());
// Save encrypted text to encrypted.txt
Files.write(Paths.get("encrypted.txt"), encrypted.getBytes());
} catch (Exception e) {
System.out.println("Error processing the file: " + e.getMessage());
}
break;
case 2:
try {
// Read encrypted text from the encrypted.txt
String encryptedText = new String(Files.readAllBytes(Paths.get("encrypted.txt"))).toUpperCase()
.trim();
String decrypted = decrypt(encryptedText);
System.out.println("Decrypted: " + decrypted);
// Save decrypted text to decrypted.txt
Files.write(Paths.get("decrypted.txt"), decrypted.getBytes());
} catch (Exception e) {
System.out.println("Error processing the file: " + e.getMessage());
}
break;
case 3:
try {
String DictionaryPath = "dictionary.txt";
// Read encrypted text from the encrypted.txt
String encryptedText = new String(Files.readAllBytes(Paths.get("encrypted.txt"))).toUpperCase()
.trim();
String decrypted = Cryptanalysis(encryptedText, DictionaryPath);
System.out.println("nDecrypted String: " + decrypted);
// Save decrypted text to decrypted.txt
Files.write(Paths.get("decrypted.txt"), decrypted.getBytes());
} catch (Exception e) {
System.out.println("Error processing the file: " + e.getMessage());
}
break;
case 4:
System.out.println("Exiting...");
keepRunning = false; // Update keepRunning to exit the loop
break;
default:
System.out.println("Invalid choice. Please choose again.");
}
} catch (NoSuchElementException e) {
// Handle NoSuchElementException (though unlikely with hasNextInt() check)
System.err.println("Input error: " + e.getMessage());
keepRunning = false; // Exit the loop on input error
}
} while (keepRunning);
scanner.close();
System.out.println("Program stopped.");
}
choice 3 contains some functions here they are ( I skipped some functions that doesn’t matter) :
public static String Cryptanalysis(String encryptedText, String DictionaryPath) throws IOException {
StringBuilder finalText = new StringBuilder(encryptedText); // Copy of the original text
int i = 0;
int count = 0;
while (i < encryptedText.length()) {
int blockStart = i; // Starting index of the current block
StringBuilder block = new StringBuilder();
int charCount = 0;
// Collect a block of 20 letters or until the end of the string
while (charCount < 20 && i < encryptedText.length()) {
char currentChar = encryptedText.charAt(i);
if (Character.isLetter(currentChar)) {
block.append(currentChar);
charCount++;
} else {
block.append(currentChar); // Include non-alphabetic characters as is
}
i++;
}
if (count % 2 != 0) { // Apply decryption to every second block
String decryptedBlock = CeaserBruteForce(block.toString(), DictionaryPath);
// Replace the encrypted block with the decrypted one in the final text
finalText.replace(blockStart, i, decryptedBlock);
}
count++;
}
processLine(encryptedText, oddKassemBlocks);
// Print oddKassemBlocks or perform further processing
for (String block : oddKassemBlocks) {
System.out.println(block);
}
Map<Character, Integer> frequencyMap = calculateLetterFrequency(oddKassemBlocks);
List<FrequencyPair> frequencyList = new ArrayList<>(frequencyMap.entrySet()).stream()
.map(entry -> new FrequencyPair(entry.getKey(), entry.getValue()))
.sorted(Collections.reverseOrder())
.toList();
System.out.println("nLetter Frequency (Descending Order):");
printFrequencyDescending(frequencyList);
Map<Character, Character> replacementDict = createReplacementDict(frequencyList);
System.out.println("nReplacement Dictionary:");
printReplacementDict(replacementDict);
String finalReplacedLetters = printFinalReplacedLetters(oddKassemBlocks, replacementDict);
// Perform word analysis
analyzeWords(finalReplacedLetters);
// Write the final text to "AnalysisDecrypt.txt"
Files.write(Paths.get("AnalysisDecrypt.txt"), finalText.toString().getBytes());
return finalText.toString();
}
private static Map<Character, Character> createReplacementDict(List frequencyList) {
Map<Character, Character> replacementDict = new HashMap<>();
String Frequency_letters = “ETAOINSRHDLUCMFWGYPBVKJXQZ”;
Scanner scanner = new Scanner(System.in);
int orderIndex = 0; // Index to track the current position in the replacement order
for (int i = 0; i < frequencyList.size(); i++) {
FrequencyPair pair = frequencyList.get(i);
char originalLetter = pair.letter;
int frequency = pair.frequency;
// Check if there are multiple letters with the same frequency
if (i < frequencyList.size() - 1 && frequencyList.get(i + 1).frequency == frequency) {
List<Character> sameFrequencyLetters = new ArrayList<>();
sameFrequencyLetters.add(originalLetter);
// Collect all letters with the same frequency
while (i < frequencyList.size() - 1 && frequencyList.get(i + 1).frequency == frequency) {
i++;
sameFrequencyLetters.add(frequencyList.get(i).letter);
}
// Display letters with the same frequency
System.out.println("nLetters with the same frequency (" + frequency + "): " + sameFrequencyLetters);
// Prompt the user to decide the order for letters with the same frequency
System.out.println("Enter the replacement order for the above letters (e.g., ABC), or type 'stop' to finish: ");
String replacementOrder = scanner.next();
if (replacementOrder.equalsIgnoreCase("stop")) {
break; // Stop the replacement process
}
// Use the replacement order provided by the user
for (char replacementLetter : replacementOrder.toCharArray()) {
int index = sameFrequencyLetters.indexOf(replacementLetter);
if (index != -1) {
char replacedLetter = sameFrequencyLetters.remove(index);
replacementDict.put(replacedLetter, Frequency_letters.charAt(orderIndex));
System.out.println(
"Replacing " + replacedLetter + " with: " + Frequency_letters.charAt(orderIndex));
orderIndex++;
}
}
} else {
char replacementLetter = Frequency_letters.charAt(orderIndex);
replacementDict.put(originalLetter, replacementLetter);
System.out.println("Replacing " + originalLetter + " with: " + replacementLetter);
orderIndex++;
}
}
// Print the final replacement dictionary
printReplacementDict(replacementDict);
// Ask the user if they are satisfied with the replacement process
System.out.println("Are you satisfied with the replacement process? (yes/no)");
String satisfactionResponse = scanner.next();
while (!satisfactionResponse.equalsIgnoreCase("yes")) {
// User is not satisfied, allow custom substitutions
System.out.println("Enter two letters for custom substitution (e.g., AB), or type 'stop' to finish: ");
String customSubstitution = scanner.next();
if (customSubstitution.equalsIgnoreCase("stop")) {
break; // Stop the custom substitution process
}
if (customSubstitution.length() == 2) {
char original = customSubstitution.charAt(0);
char substitute = customSubstitution.charAt(1);
replacementDict.put(original, substitute);
System.out.println("Custom substitution: Replacing " + original + " with " + substitute);
} else {
System.out.println("Invalid input. Please enter two letters or 'stop'.");
}
// Ask the user again if they are satisfied
System.out.println("Are you satisfied with the replacement process? (yes/no)");
satisfactionResponse = scanner.next();
scanner.nextLine(); // Consume the invalid input
scanner.nextInt(); // Consume the invalid input
}
scanner.close();
return replacementDict;
}
Kassem Darawcha is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.