From 4a043aaec771cc6b14208c444b72365b96d95fdf Mon Sep 17 00:00:00 2001 From: Denys Date: Wed, 4 Sep 2024 18:34:22 +0300 Subject: [PATCH 01/21] Add some files --- .../javarush/gnew/Constants/Constants.java | 16 ++++ .../javarush/gnew/Dictionary/Dictionary.java | 7 ++ src/main/java/ua/com/javarush/gnew/Main.java | 40 ++++++++-- .../javarush/gnew/crypto/Cryptanalyzer.java | 69 +++++++++++++++++ .../ua/com/javarush/gnew/crypto/Cypher.java | 33 -------- .../javarush/gnew/crypto/RunBruteforce.java | 77 +++++++++++++++++++ .../com/javarush/gnew/file/FileManager.java | 9 +-- .../com/javarush/gnew/language/Language.java | 12 --- .../javarush/gnew/runner/ArgumentsParser.java | 72 ++++++----------- .../com/javarush/gnew/runner/RunOptions.java | 26 +------ 10 files changed, 230 insertions(+), 131 deletions(-) create mode 100644 src/main/java/ua/com/javarush/gnew/Constants/Constants.java create mode 100644 src/main/java/ua/com/javarush/gnew/Dictionary/Dictionary.java create mode 100644 src/main/java/ua/com/javarush/gnew/crypto/Cryptanalyzer.java delete mode 100644 src/main/java/ua/com/javarush/gnew/crypto/Cypher.java create mode 100644 src/main/java/ua/com/javarush/gnew/crypto/RunBruteforce.java delete mode 100644 src/main/java/ua/com/javarush/gnew/language/Language.java diff --git a/src/main/java/ua/com/javarush/gnew/Constants/Constants.java b/src/main/java/ua/com/javarush/gnew/Constants/Constants.java new file mode 100644 index 0000000..c61b6a1 --- /dev/null +++ b/src/main/java/ua/com/javarush/gnew/Constants/Constants.java @@ -0,0 +1,16 @@ +package ua.com.javarush.gnew.Constants; + +import java.util.ArrayList; +import java.util.Arrays; + + public class Constants { + public static final ArrayList ENG = new ArrayList<>(Arrays.asList( + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z')); + + public static final ArrayList UKR = new ArrayList<>(Arrays.asList( + 'а', 'б', 'в', 'г', 'ґ', 'д', 'е', 'є', 'ж', 'з', 'и', 'і', 'ї', 'й', 'к', 'л', 'м', 'н', 'о', 'п', 'р', 'с', 'т', 'у', 'ф', 'х', 'ц', 'ч', 'ш', 'щ', 'ь', 'ю', 'я', + 'А', 'Б', 'В', 'Г', 'Ґ', 'Д', 'Е', 'Є', 'Ж', 'З', 'И', 'І', 'Ї', 'Й', 'К', 'Л', 'М', 'Н', 'О', 'П', 'Р', 'С', 'Т', 'У', 'Ф', 'Х', 'Ц', 'Ч', 'Ш', 'Щ', 'Ь', 'Ю', 'Я')); + } + + diff --git a/src/main/java/ua/com/javarush/gnew/Dictionary/Dictionary.java b/src/main/java/ua/com/javarush/gnew/Dictionary/Dictionary.java new file mode 100644 index 0000000..941536d --- /dev/null +++ b/src/main/java/ua/com/javarush/gnew/Dictionary/Dictionary.java @@ -0,0 +1,7 @@ +package ua.com.javarush.gnew.Dictionary; + +public class Dictionary { + public static final String[] dictionary = new String[]{"take","or","for","of","as","his","that","he","was","for","on","are","with","they","be","at","by","word","have","play","my","world","there","those","victory","is","not","to","in","the"}; + public static final String[] dictionaryUKR = new String[]{"Ми", "всі", "щось","Привіт","хто","що","коли","слово","ти","він","вона","воно","вони","йому","робить","працює","каже","розмовляє","співає","чує","що робить","збирає","поле","був","була","ні","так","тому що"}; + } + diff --git a/src/main/java/ua/com/javarush/gnew/Main.java b/src/main/java/ua/com/javarush/gnew/Main.java index 5906828..cdcc7d3 100644 --- a/src/main/java/ua/com/javarush/gnew/Main.java +++ b/src/main/java/ua/com/javarush/gnew/Main.java @@ -1,6 +1,9 @@ package ua.com.javarush.gnew; -import ua.com.javarush.gnew.crypto.Cypher; + + +import ua.com.javarush.gnew.crypto.Cryptanalyzer; +import ua.com.javarush.gnew.crypto.RunBruteforce; import ua.com.javarush.gnew.file.FileManager; import ua.com.javarush.gnew.runner.ArgumentsParser; import ua.com.javarush.gnew.runner.Command; @@ -8,25 +11,46 @@ import java.nio.file.Path; +import static ua.com.javarush.gnew.Dictionary.Dictionary.dictionary; +import static ua.com.javarush.gnew.Dictionary.Dictionary.dictionaryUKR; + + public class Main { public static void main(String[] args) { - Cypher cypher = new Cypher(); + Cryptanalyzer cryptanalyzer = new Cryptanalyzer(); + RunBruteforce runBruteforce = new RunBruteforce(); FileManager fileManager = new FileManager(); ArgumentsParser argumentsParser = new ArgumentsParser(); - RunOptions runOptions = argumentsParser.parse(args); - + RunOptions runOptions = argumentsParser.parse(); try { if (runOptions.getCommand() == Command.ENCRYPT) { String content = fileManager.read(runOptions.getFilePath()); - String encryptedContent = cypher.encrypt(content, runOptions.getKey()); + String encryptedContent = cryptanalyzer.encryption(content, runOptions.getKey()); String fileName = runOptions.getFilePath().getFileName().toString(); String newFileName = fileName.substring(0, fileName.length() - 4) + " [ENCRYPTED].txt"; + Path newFilePath = runOptions.getFilePath().resolveSibling(newFileName); + fileManager.write(newFilePath, encryptedContent); + } else if (runOptions.getCommand() == Command.DECRYPT) { + String content = fileManager.read(runOptions.getFilePath()); + String encryptedContent = cryptanalyzer.decryption(content, runOptions.getKey()); + String fileName = runOptions.getFilePath().getFileName().toString(); + String newFileName = fileName.substring(0, fileName.length() - 4) + " [DECRYPTED].txt"; + + Path newFilePath = runOptions.getFilePath().resolveSibling(newFileName); + fileManager.write(newFilePath, encryptedContent); + } else if (runOptions.getCommand() == Command.BRUTEFORCE) { + String content = fileManager.read(runOptions.getFilePath()); + String encryptedContent = runBruteforce.bruteforce(content,dictionary, dictionaryUKR); + String fileName = runOptions.getFilePath().getFileName().toString(); + String key = runBruteforce.getKey(content, dictionary, dictionaryUKR).replace("Key: ", ""); + String newFileName = fileName.substring(0, fileName.length() - 4) + " [DECRYPTED Key -" + key+ "].txt"; + Path newFilePath = runOptions.getFilePath().resolveSibling(newFileName); fileManager.write(newFilePath, encryptedContent); } - } catch (Exception e) { - System.out.println(e.getMessage()); + }catch (Exception e){ + System.out.println("Smth went wrong"); } } -} \ No newline at end of file +} diff --git a/src/main/java/ua/com/javarush/gnew/crypto/Cryptanalyzer.java b/src/main/java/ua/com/javarush/gnew/crypto/Cryptanalyzer.java new file mode 100644 index 0000000..04004e9 --- /dev/null +++ b/src/main/java/ua/com/javarush/gnew/crypto/Cryptanalyzer.java @@ -0,0 +1,69 @@ +package ua.com.javarush.gnew.crypto; + +import ua.com.javarush.gnew.Constants.Constants; + +import java.util.ArrayList; +import java.util.Collections; + +import static ua.com.javarush.gnew.Constants.Constants.ENG; +import static ua.com.javarush.gnew.Constants.Constants.UKR; + + +public class Cryptanalyzer { + + public String encryption(String str, int key){ + key = Math.negateExact(key); + ArrayList ENG_MOD = new ArrayList<>(ENG); + ArrayList UKR_MOD = new ArrayList<>(UKR); + Collections.rotate(ENG_MOD, key); + Collections.rotate(UKR_MOD, key); + char[] array = str.toCharArray(); + StringBuilder builder = new StringBuilder(); + + for (char symbol : array) { + int originalIndex = ENG.indexOf(symbol); + if (originalIndex != -1) { + Character encrypted = ENG_MOD.get(originalIndex); + builder.append(encrypted); + continue; + } + + int GettingIndex = UKR.indexOf(symbol); + if (GettingIndex != -1) { + Character encrypted = UKR_MOD.get(GettingIndex); + builder.append(encrypted); + }else{ + builder.append(symbol); + } + + } + + return builder.toString(); + } + public String decryption(String str, int key) { + ArrayList ENG_MOD = new ArrayList<>(ENG); + ArrayList UKR_MOD = new ArrayList<>(UKR); + Collections.rotate(ENG_MOD, key); + Collections.rotate(UKR_MOD, key); + char[] array = str.toCharArray(); + StringBuilder builder = new StringBuilder(); + + for (char symbol : array) { + int originalIndex = ENG.indexOf(symbol); + if (originalIndex != -1) { + Character encrypted = ENG_MOD.get(originalIndex); + builder.append(encrypted); + continue; + } + + int GettingIndex = UKR.indexOf(symbol); + if (GettingIndex != -1) { + Character encrypted = UKR_MOD.get(GettingIndex); + builder.append(encrypted); + } else { + builder.append(symbol); + } + } + return builder.toString(); + } +} diff --git a/src/main/java/ua/com/javarush/gnew/crypto/Cypher.java b/src/main/java/ua/com/javarush/gnew/crypto/Cypher.java deleted file mode 100644 index 2b01247..0000000 --- a/src/main/java/ua/com/javarush/gnew/crypto/Cypher.java +++ /dev/null @@ -1,33 +0,0 @@ -package ua.com.javarush.gnew.crypto; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; - -public class Cypher { - private final ArrayList originalAlphabet = new ArrayList<>(Arrays.asList('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z')); - - - public String encrypt(String input, int key) { - key = Math.negateExact(key); - - ArrayList rotatedAlphabet = new ArrayList<>(originalAlphabet); - Collections.rotate(rotatedAlphabet, key); - char[] charArray = input.toCharArray(); - - StringBuilder builder = new StringBuilder(); - for (char symbol : charArray) { - builder.append(processSymbol(symbol, rotatedAlphabet)); - } - return builder.toString(); - } - - private Character processSymbol(char symbol, ArrayList rotatedAlphabet) { - if (!originalAlphabet.contains(symbol)) { - return symbol; - } - int index = originalAlphabet.indexOf(symbol); - - return rotatedAlphabet.get(index); - } -} diff --git a/src/main/java/ua/com/javarush/gnew/crypto/RunBruteforce.java b/src/main/java/ua/com/javarush/gnew/crypto/RunBruteforce.java new file mode 100644 index 0000000..6be7790 --- /dev/null +++ b/src/main/java/ua/com/javarush/gnew/crypto/RunBruteforce.java @@ -0,0 +1,77 @@ +package ua.com.javarush.gnew.crypto; + +import java.util.ArrayList; +import java.util.Collections; + +import static ua.com.javarush.gnew.Constants.Constants.ENG; + + public class RunBruteforce { + public String bruteforce(String str, String[] dictionary, String[] dictionaryUKR) { + char[] array = str.toCharArray(); + String bestMatch = null; + int maxMatches = 0; + for (int key = 0; key < ENG.size(); key++) { + ArrayList ENG_MOD = new ArrayList<>(ENG); + Collections.rotate(ENG_MOD, key); + StringBuilder builder = new StringBuilder(); + for (char symbol : array) { + int originalIndex = ENG.indexOf(symbol); + if (originalIndex != -1) { + Character encrypted = ENG_MOD.get(originalIndex); + builder.append(encrypted); + } else { + builder.append(symbol); + } + } + String DecryptedText = builder.toString(); + int matches = 0; + for (String words : dictionary) { + if (DecryptedText.contains(words)) { + matches++; + } + } + //System.out.println("Key: " + key + " DecryptedText: " + DecryptedText + " Matches: " + matches); + + if (matches > maxMatches) { + maxMatches = matches; + bestMatch = DecryptedText; + } + } + return bestMatch != null ? bestMatch : "Брутфорс не дал результатов."; + } + public String getKey(String str, String[] dictionary, String[] dictionaryUKR) { + + char[] array = str.toCharArray(); + int maxMatches = 0; + String KeyResult = null; + for (int key = 0; key < ENG.size(); key++) { + ArrayList ENG_MOD = new ArrayList<>(ENG); + Collections.rotate(ENG_MOD, key); + StringBuilder builder = new StringBuilder(); + for (char symbol : array) { + int originalIndex = ENG.indexOf(symbol); + if (originalIndex != -1) { + Character encrypted = ENG_MOD.get(originalIndex); + builder.append(encrypted); + } else { + builder.append(symbol); + } + } + String DecryptedText = builder.toString(); + int matches = 0; + for (String words : dictionary) { + if (DecryptedText.contains(words)) { + matches++; + } + } + //System.out.println("Key: " + key + " DecryptedText: " + DecryptedText + " Matches: " + matches); + + if (matches > maxMatches) { + maxMatches = matches; + KeyResult = "Key: " + key; + } + } + return KeyResult; + } + } + diff --git a/src/main/java/ua/com/javarush/gnew/file/FileManager.java b/src/main/java/ua/com/javarush/gnew/file/FileManager.java index d60744c..233f21d 100644 --- a/src/main/java/ua/com/javarush/gnew/file/FileManager.java +++ b/src/main/java/ua/com/javarush/gnew/file/FileManager.java @@ -5,11 +5,10 @@ import java.nio.file.Path; public class FileManager { - public String read(Path filePath) throws IOException { - return Files.readString(filePath); + public String read(Path FilePath) throws IOException{ + return Files.readString(FilePath); } - - public void write(Path filePath, String content) throws IOException { - Files.writeString(filePath, content); + public void write(Path FilePath, String content) throws IOException{ + Files.writeString(FilePath,content); } } diff --git a/src/main/java/ua/com/javarush/gnew/language/Language.java b/src/main/java/ua/com/javarush/gnew/language/Language.java deleted file mode 100644 index 067dd2f..0000000 --- a/src/main/java/ua/com/javarush/gnew/language/Language.java +++ /dev/null @@ -1,12 +0,0 @@ -package ua.com.javarush.gnew.language; - -import java.util.ArrayList; - -public abstract class Language { - - private final ArrayList alphabet; - - public Language(ArrayList alphabet) { - this.alphabet = alphabet; - } -} diff --git a/src/main/java/ua/com/javarush/gnew/runner/ArgumentsParser.java b/src/main/java/ua/com/javarush/gnew/runner/ArgumentsParser.java index eb42462..68bf119 100644 --- a/src/main/java/ua/com/javarush/gnew/runner/ArgumentsParser.java +++ b/src/main/java/ua/com/javarush/gnew/runner/ArgumentsParser.java @@ -1,62 +1,38 @@ package ua.com.javarush.gnew.runner; import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Scanner; public class ArgumentsParser { - public RunOptions parse(String[] args) { - Command command = null; + public RunOptions parse() { + Scanner input = new Scanner(System.in); + Command command; Integer key = null; - Path filePath = null; - - for (int i = 0; i < args.length; i++) { - String arg = args[i]; - - switch (arg) { - case "-e": - command = Command.ENCRYPT; - break; - - case "-d": - command = Command.DECRYPT; - break; - - case "-bf": - command = Command.BRUTEFORCE; - break; - case "-k": - if (i + 1 < args.length) { - key = Integer.parseInt(args[++i]); - } else { - throw new IllegalArgumentException("Missing value for key"); - } - break; - - case "-f": - if (i + 1 < args.length) { - filePath = Path.of(args[++i]); - } else { - throw new IllegalArgumentException("Missing value for file"); - } - break; - - default: - throw new IllegalArgumentException("Unknown argument: " + arg); - } + Path filePath ; + + System.out.println("Введите команду (e - encrypt, d - decrypt, bf - bruteforce):"); + String commandInput = input.nextLine().trim(); + + if (commandInput.equalsIgnoreCase("e")) { + command = Command.ENCRYPT; + } else if (commandInput.equalsIgnoreCase("d")) { + command = Command.DECRYPT; + } else if (commandInput.equalsIgnoreCase("bf")) { + command = Command.BRUTEFORCE; + } else { + throw new IllegalArgumentException("Неизвестная команда. Ожидалась команда (e, d, или bf)"); } - if (command == null) { - throw new IllegalArgumentException("Command (-e, -d, or -bf) is required"); + if (command == Command.ENCRYPT || command == Command.DECRYPT) { + System.out.println("Введите ключ для шифрования/дешифрования:"); + key = Integer.parseInt(input.nextLine().trim()); } - if (key == null) { - throw new IllegalArgumentException("Key is required for encrypt or decrypt mode"); - } - - if (filePath == null) { - throw new IllegalArgumentException("File path is required"); - } + System.out.println("Введите путь к файлу:"); + String filePathInput = input.nextLine().trim(); + filePath = Paths.get(filePathInput); return new RunOptions(command, key, filePath); } - } diff --git a/src/main/java/ua/com/javarush/gnew/runner/RunOptions.java b/src/main/java/ua/com/javarush/gnew/runner/RunOptions.java index 45e700b..b9eef08 100644 --- a/src/main/java/ua/com/javarush/gnew/runner/RunOptions.java +++ b/src/main/java/ua/com/javarush/gnew/runner/RunOptions.java @@ -3,26 +3,11 @@ import java.nio.file.Path; public class RunOptions { - /** - * Command to be executed. - * -e option for encryption. - * -d option for decryption. - * -b option for brute force. - */ + private final Command command; - /** - * Key to be used for encryption or decryption. - * For encryption mode, this is the shift value. - * -k option is required. - */ private final Integer key; - /** - * Path to the file to be processed. - * For encryption and decryption modes, this is the file to be encrypted or decrypted. - * -f option is required. - */ private final Path filePath; public RunOptions(Command command, Integer key, Path filePath) { @@ -42,13 +27,4 @@ public Integer getKey() { public Path getFilePath() { return filePath; } - - @Override - public String toString() { - return "CommandOptions{" + - "command='" + command + '\'' + - ", key=" + key + - ", filePath=" + filePath + - '}'; - } } From 46231c41f00de30fe416a006295e5dcf9eb2d78d Mon Sep 17 00:00:00 2001 From: Denys Date: Wed, 4 Sep 2024 18:37:40 +0300 Subject: [PATCH 02/21] Add some files --- src/main/java/ua/com/javarush/gnew/Constants/Constants.java | 1 - src/main/java/ua/com/javarush/gnew/Dictionary/Dictionary.java | 1 + src/main/java/ua/com/javarush/gnew/Main.java | 2 +- src/main/java/ua/com/javarush/gnew/crypto/Cryptanalyzer.java | 1 - src/main/java/ua/com/javarush/gnew/crypto/RunBruteforce.java | 1 - src/main/java/ua/com/javarush/gnew/file/FileManager.java | 1 + src/main/java/ua/com/javarush/gnew/runner/ArgumentsParser.java | 1 + src/main/java/ua/com/javarush/gnew/runner/RunOptions.java | 1 + 8 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/java/ua/com/javarush/gnew/Constants/Constants.java b/src/main/java/ua/com/javarush/gnew/Constants/Constants.java index c61b6a1..4ceeec7 100644 --- a/src/main/java/ua/com/javarush/gnew/Constants/Constants.java +++ b/src/main/java/ua/com/javarush/gnew/Constants/Constants.java @@ -7,7 +7,6 @@ public class Constants { public static final ArrayList ENG = new ArrayList<>(Arrays.asList( 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z')); - public static final ArrayList UKR = new ArrayList<>(Arrays.asList( 'а', 'б', 'в', 'г', 'ґ', 'д', 'е', 'є', 'ж', 'з', 'и', 'і', 'ї', 'й', 'к', 'л', 'м', 'н', 'о', 'п', 'р', 'с', 'т', 'у', 'ф', 'х', 'ц', 'ч', 'ш', 'щ', 'ь', 'ю', 'я', 'А', 'Б', 'В', 'Г', 'Ґ', 'Д', 'Е', 'Є', 'Ж', 'З', 'И', 'І', 'Ї', 'Й', 'К', 'Л', 'М', 'Н', 'О', 'П', 'Р', 'С', 'Т', 'У', 'Ф', 'Х', 'Ц', 'Ч', 'Ш', 'Щ', 'Ь', 'Ю', 'Я')); diff --git a/src/main/java/ua/com/javarush/gnew/Dictionary/Dictionary.java b/src/main/java/ua/com/javarush/gnew/Dictionary/Dictionary.java index 941536d..c02df8b 100644 --- a/src/main/java/ua/com/javarush/gnew/Dictionary/Dictionary.java +++ b/src/main/java/ua/com/javarush/gnew/Dictionary/Dictionary.java @@ -2,6 +2,7 @@ public class Dictionary { public static final String[] dictionary = new String[]{"take","or","for","of","as","his","that","he","was","for","on","are","with","they","be","at","by","word","have","play","my","world","there","those","victory","is","not","to","in","the"}; + public static final String[] dictionaryUKR = new String[]{"Ми", "всі", "щось","Привіт","хто","що","коли","слово","ти","він","вона","воно","вони","йому","робить","працює","каже","розмовляє","співає","чує","що робить","збирає","поле","був","була","ні","так","тому що"}; } diff --git a/src/main/java/ua/com/javarush/gnew/Main.java b/src/main/java/ua/com/javarush/gnew/Main.java index cdcc7d3..a447102 100644 --- a/src/main/java/ua/com/javarush/gnew/Main.java +++ b/src/main/java/ua/com/javarush/gnew/Main.java @@ -14,7 +14,6 @@ import static ua.com.javarush.gnew.Dictionary.Dictionary.dictionary; import static ua.com.javarush.gnew.Dictionary.Dictionary.dictionaryUKR; - public class Main { public static void main(String[] args) { Cryptanalyzer cryptanalyzer = new Cryptanalyzer(); @@ -49,6 +48,7 @@ public static void main(String[] args) { Path newFilePath = runOptions.getFilePath().resolveSibling(newFileName); fileManager.write(newFilePath, encryptedContent); } + }catch (Exception e){ System.out.println("Smth went wrong"); } diff --git a/src/main/java/ua/com/javarush/gnew/crypto/Cryptanalyzer.java b/src/main/java/ua/com/javarush/gnew/crypto/Cryptanalyzer.java index 04004e9..cfd836c 100644 --- a/src/main/java/ua/com/javarush/gnew/crypto/Cryptanalyzer.java +++ b/src/main/java/ua/com/javarush/gnew/crypto/Cryptanalyzer.java @@ -10,7 +10,6 @@ public class Cryptanalyzer { - public String encryption(String str, int key){ key = Math.negateExact(key); ArrayList ENG_MOD = new ArrayList<>(ENG); diff --git a/src/main/java/ua/com/javarush/gnew/crypto/RunBruteforce.java b/src/main/java/ua/com/javarush/gnew/crypto/RunBruteforce.java index 6be7790..ff55c9f 100644 --- a/src/main/java/ua/com/javarush/gnew/crypto/RunBruteforce.java +++ b/src/main/java/ua/com/javarush/gnew/crypto/RunBruteforce.java @@ -31,7 +31,6 @@ public String bruteforce(String str, String[] dictionary, String[] dictionaryUKR } } //System.out.println("Key: " + key + " DecryptedText: " + DecryptedText + " Matches: " + matches); - if (matches > maxMatches) { maxMatches = matches; bestMatch = DecryptedText; diff --git a/src/main/java/ua/com/javarush/gnew/file/FileManager.java b/src/main/java/ua/com/javarush/gnew/file/FileManager.java index 233f21d..638f7c0 100644 --- a/src/main/java/ua/com/javarush/gnew/file/FileManager.java +++ b/src/main/java/ua/com/javarush/gnew/file/FileManager.java @@ -8,6 +8,7 @@ public class FileManager { public String read(Path FilePath) throws IOException{ return Files.readString(FilePath); } + public void write(Path FilePath, String content) throws IOException{ Files.writeString(FilePath,content); } diff --git a/src/main/java/ua/com/javarush/gnew/runner/ArgumentsParser.java b/src/main/java/ua/com/javarush/gnew/runner/ArgumentsParser.java index 68bf119..040e56b 100644 --- a/src/main/java/ua/com/javarush/gnew/runner/ArgumentsParser.java +++ b/src/main/java/ua/com/javarush/gnew/runner/ArgumentsParser.java @@ -24,6 +24,7 @@ public RunOptions parse() { throw new IllegalArgumentException("Неизвестная команда. Ожидалась команда (e, d, или bf)"); } + if (command == Command.ENCRYPT || command == Command.DECRYPT) { System.out.println("Введите ключ для шифрования/дешифрования:"); key = Integer.parseInt(input.nextLine().trim()); diff --git a/src/main/java/ua/com/javarush/gnew/runner/RunOptions.java b/src/main/java/ua/com/javarush/gnew/runner/RunOptions.java index b9eef08..5073768 100644 --- a/src/main/java/ua/com/javarush/gnew/runner/RunOptions.java +++ b/src/main/java/ua/com/javarush/gnew/runner/RunOptions.java @@ -10,6 +10,7 @@ public class RunOptions { private final Path filePath; + public RunOptions(Command command, Integer key, Path filePath) { this.command = command; this.key = key; From ed55cb380dffd621abdfbbdb8c8266f8451592a7 Mon Sep 17 00:00:00 2001 From: Denys Date: Wed, 4 Sep 2024 18:42:49 +0300 Subject: [PATCH 03/21] Add some files --- src/main/java/ua/com/javarush/gnew/Main.java | 4 ++-- .../gnew/{crypto => crypt/code}/Cryptanalyzer.java | 2 +- .../gnew/{crypto => crypt/code}/RunBruteforce.java | 2 +- src/test/java/ua/com/javarush/gnew/MainTest.java | 8 ++++---- 4 files changed, 8 insertions(+), 8 deletions(-) rename src/main/java/ua/com/javarush/gnew/{crypto => crypt/code}/Cryptanalyzer.java (98%) rename src/main/java/ua/com/javarush/gnew/{crypto => crypt/code}/RunBruteforce.java (98%) diff --git a/src/main/java/ua/com/javarush/gnew/Main.java b/src/main/java/ua/com/javarush/gnew/Main.java index a447102..7037a50 100644 --- a/src/main/java/ua/com/javarush/gnew/Main.java +++ b/src/main/java/ua/com/javarush/gnew/Main.java @@ -2,8 +2,8 @@ -import ua.com.javarush.gnew.crypto.Cryptanalyzer; -import ua.com.javarush.gnew.crypto.RunBruteforce; +import ua.com.javarush.gnew.crypt.code.Cryptanalyzer; +import ua.com.javarush.gnew.crypt.code.RunBruteforce; import ua.com.javarush.gnew.file.FileManager; import ua.com.javarush.gnew.runner.ArgumentsParser; import ua.com.javarush.gnew.runner.Command; diff --git a/src/main/java/ua/com/javarush/gnew/crypto/Cryptanalyzer.java b/src/main/java/ua/com/javarush/gnew/crypt/code/Cryptanalyzer.java similarity index 98% rename from src/main/java/ua/com/javarush/gnew/crypto/Cryptanalyzer.java rename to src/main/java/ua/com/javarush/gnew/crypt/code/Cryptanalyzer.java index cfd836c..b186247 100644 --- a/src/main/java/ua/com/javarush/gnew/crypto/Cryptanalyzer.java +++ b/src/main/java/ua/com/javarush/gnew/crypt/code/Cryptanalyzer.java @@ -1,4 +1,4 @@ -package ua.com.javarush.gnew.crypto; +package ua.com.javarush.gnew.crypt.code; import ua.com.javarush.gnew.Constants.Constants; diff --git a/src/main/java/ua/com/javarush/gnew/crypto/RunBruteforce.java b/src/main/java/ua/com/javarush/gnew/crypt/code/RunBruteforce.java similarity index 98% rename from src/main/java/ua/com/javarush/gnew/crypto/RunBruteforce.java rename to src/main/java/ua/com/javarush/gnew/crypt/code/RunBruteforce.java index ff55c9f..c5e4117 100644 --- a/src/main/java/ua/com/javarush/gnew/crypto/RunBruteforce.java +++ b/src/main/java/ua/com/javarush/gnew/crypt/code/RunBruteforce.java @@ -1,4 +1,4 @@ -package ua.com.javarush.gnew.crypto; +package ua.com.javarush.gnew.crypt.code; import java.util.ArrayList; import java.util.Collections; diff --git a/src/test/java/ua/com/javarush/gnew/MainTest.java b/src/test/java/ua/com/javarush/gnew/MainTest.java index b7f6356..5a67722 100644 --- a/src/test/java/ua/com/javarush/gnew/MainTest.java +++ b/src/test/java/ua/com/javarush/gnew/MainTest.java @@ -15,10 +15,10 @@ import static org.junit.jupiter.api.Assertions.*; class MainTest { - private static final boolean UKRAINIAN_LANGUAGE_TEST = false; - private static final String ENCRYPT_COMMAND = "-e"; - private static final String DECRYPT_COMMAND = "-d"; - private static final String BF_COMMAND = "-bf"; + private static final boolean UKRAINIAN_LANGUAGE_TEST = true; + private static final String ENCRYPT_COMMAND = "e"; + private static final String DECRYPT_COMMAND = "d"; + private static final String BF_COMMAND = "bf"; private static final String HAMLET_EN = """ THE TRAGEDY OF HAMLET, PRINCE OF DENMARK From 044524017da4dd59d9d59020636cd4b857bcf7ba Mon Sep 17 00:00:00 2001 From: Denys Date: Wed, 4 Sep 2024 18:45:17 +0300 Subject: [PATCH 04/21] Add some files --- src/main/java/ua/com/javarush/gnew/Main.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/ua/com/javarush/gnew/Main.java b/src/main/java/ua/com/javarush/gnew/Main.java index 7037a50..b8dbd6a 100644 --- a/src/main/java/ua/com/javarush/gnew/Main.java +++ b/src/main/java/ua/com/javarush/gnew/Main.java @@ -48,7 +48,6 @@ public static void main(String[] args) { Path newFilePath = runOptions.getFilePath().resolveSibling(newFileName); fileManager.write(newFilePath, encryptedContent); } - }catch (Exception e){ System.out.println("Smth went wrong"); } From 64317318c5c3831cb2de5e4edcf7f7eb047cdf6c Mon Sep 17 00:00:00 2001 From: Denys Date: Wed, 4 Sep 2024 18:59:52 +0300 Subject: [PATCH 05/21] Add some files --- readme.md | 23 ++++++------------- .../java/ua/com/javarush/gnew/MainTest.java | 4 ++-- 2 files changed, 9 insertions(+), 18 deletions(-) diff --git a/readme.md b/readme.md index a17a9ac..c9ef08e 100644 --- a/readme.md +++ b/readme.md @@ -1,28 +1,19 @@ +Commands: -## Run the program - -### Commands: - -``` -e Encrypt -d Decrypt -bf Brute force -``` +Arguments: -### Arguments: -``` -k Key -f File path -``` -### Example: -``` +Example: + -e -k 1 -f "/path/to/file.txt" - Encrypt file with key 1 -d -k 5 -f "/path/to/file [ENCRYPTED].txt" - Decrypt file with key 5 -bf -f "/path/to/file [ENCRYPTED].txt" - Brute force decrypt file -``` -### Argument could be in any order -``` --e -f "/path/to/file.txt" -k 1 -``` \ No newline at end of file +Argument could be in any order + +-e -f "/path/to/file.txt" -k 1 \ No newline at end of file diff --git a/src/test/java/ua/com/javarush/gnew/MainTest.java b/src/test/java/ua/com/javarush/gnew/MainTest.java index 5a67722..0b54d30 100644 --- a/src/test/java/ua/com/javarush/gnew/MainTest.java +++ b/src/test/java/ua/com/javarush/gnew/MainTest.java @@ -112,7 +112,7 @@ private Path createTestFile(String fileName, String content) throws IOException private Path execute(String command, Path inputFilePath, int key) { List filesBefore = listFiles(tempDir); - List params = List.of(command, "-k", String.valueOf(key), "-f", inputFilePath.toString()); + List params = List.of(command, "k", String.valueOf(key), "f", inputFilePath.toString()); try { Main.main(params.toArray(new String[0])); @@ -343,7 +343,7 @@ void negativeKeyEncryption(String input, int key, String expected) throws IOExce void fileNotExists() { Path fakeFilePath = Path.of("/fake/path/file.txt"); - String[] params = {ENCRYPT_COMMAND, "-f", fakeFilePath.toString(), "-k", "5"}; + String[] params = {ENCRYPT_COMMAND, "f", fakeFilePath.toString(), "k", "5"}; assertDoesNotThrow(() -> Main.main(params), "Exception was thrown while processing a non-existent file path."); } From 570190e1eb5697c0e5c3b723c6ce9571a579ee02 Mon Sep 17 00:00:00 2001 From: Denys Burduzhan <151670272+DenysBurduzhan@users.noreply.github.com> Date: Wed, 4 Sep 2024 19:01:35 +0300 Subject: [PATCH 06/21] Update readme.md --- readme.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/readme.md b/readme.md index c9ef08e..cbf2ccb 100644 --- a/readme.md +++ b/readme.md @@ -1,19 +1,19 @@ Commands: --e Encrypt --d Decrypt --bf Brute force +e Encrypt +d Decrypt +bf Brute force Arguments: --k Key --f File path +k Key +f File path Example: --e -k 1 -f "/path/to/file.txt" - Encrypt file with key 1 --d -k 5 -f "/path/to/file [ENCRYPTED].txt" - Decrypt file with key 5 --bf -f "/path/to/file [ENCRYPTED].txt" - Brute force decrypt file +e 1 f "/path/to/file.txt" - Encrypt file with key 1 +d 5 f "/path/to/file [ENCRYPTED].txt" - Decrypt file with key 5 +bf f "/path/to/file [ENCRYPTED].txt" - Brute force decrypt file Argument could be in any order --e -f "/path/to/file.txt" -k 1 \ No newline at end of file +e "/path/to/file.txt" 1 From 6507ad6816615b683c1a95d2110dbf7836f7d312 Mon Sep 17 00:00:00 2001 From: Denys Date: Wed, 4 Sep 2024 19:03:35 +0300 Subject: [PATCH 07/21] Add some files --- readme.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/readme.md b/readme.md index c9ef08e..c46820f 100644 --- a/readme.md +++ b/readme.md @@ -1,19 +1,19 @@ Commands: --e Encrypt --d Decrypt --bf Brute force +e Encrypt +d Decrypt +bf Brute force Arguments: --k Key --f File path +k Key +f File path Example: --e -k 1 -f "/path/to/file.txt" - Encrypt file with key 1 --d -k 5 -f "/path/to/file [ENCRYPTED].txt" - Decrypt file with key 5 --bf -f "/path/to/file [ENCRYPTED].txt" - Brute force decrypt file +e 1 "/path/to/file.txt" - Encrypt file with key 1 +d 5 "/path/to/file [ENCRYPTED].txt" - Decrypt file with key 5 +bf f "/path/to/file [ENCRYPTED].txt" - Brute force decrypt file Argument could be in any order --e -f "/path/to/file.txt" -k 1 \ No newline at end of file +e "/path/to/file.txt" 1(kay) \ No newline at end of file From d2afba6e1eae58cf424ae79f3e2aff281f9fb9e1 Mon Sep 17 00:00:00 2001 From: Denys Burduzhan <151670272+DenysBurduzhan@users.noreply.github.com> Date: Wed, 4 Sep 2024 19:06:57 +0300 Subject: [PATCH 08/21] Update readme.md --- readme.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/readme.md b/readme.md index cbf2ccb..63adf01 100644 --- a/readme.md +++ b/readme.md @@ -1,19 +1,19 @@ Commands: -e Encrypt -d Decrypt -bf Brute force +-e Encrypt +-d Decrypt +-bf Brute force Arguments: -k Key -f File path +-k Key +-f File path Example: -e 1 f "/path/to/file.txt" - Encrypt file with key 1 -d 5 f "/path/to/file [ENCRYPTED].txt" - Decrypt file with key 5 -bf f "/path/to/file [ENCRYPTED].txt" - Brute force decrypt file +-e -k 1 -f "/path/to/file.txt" - Encrypt file with key 1 +-d -k 5 -f "/path/to/file [ENCRYPTED].txt" - Decrypt file with key 5 +-bf -f "/path/to/file [ENCRYPTED].txt" - Brute force decrypt file Argument could be in any order -e "/path/to/file.txt" 1 +-e -f "/path/to/file.txt" -k 1 From 959d5b65cc5bfe605e925e3e4cd6556c6026b76d Mon Sep 17 00:00:00 2001 From: Denys Date: Wed, 4 Sep 2024 19:26:12 +0300 Subject: [PATCH 09/21] Add some files --- readme.md | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/readme.md b/readme.md index c46820f..c51ee66 100644 --- a/readme.md +++ b/readme.md @@ -1,19 +1,20 @@ -Commands: -e Encrypt -d Decrypt -bf Brute force -Arguments: -k Key -f File path -Example: +### Commands: -e 1 "/path/to/file.txt" - Encrypt file with key 1 -d 5 "/path/to/file [ENCRYPTED].txt" - Decrypt file with key 5 -bf f "/path/to/file [ENCRYPTED].txt" - Brute force decrypt file +- e Encrypt +- d Decrypt +- bf Brute force -Argument could be in any order +### Arguments: + +- You need to write the arguments in the order: encrypt/decrypt/bruteforce(e,d,bf) + key(1 or -1 and further in decreasing, increasing order) + file path. + In the case of bruteforce, a key is not needed. + +### Example: + +- e 1 "/path/to/file.txt" - Encrypt file with key 1 +- d 5 "/path/to/file [ENCRYPTED].txt" - Decrypt file with key 5 +- bf "/path/to/file [ENCRYPTED].txt" - Brute force decrypt file -e "/path/to/file.txt" 1(kay) \ No newline at end of file From 5c09dee514725f25d22c3d8f2a13d1d2373062c9 Mon Sep 17 00:00:00 2001 From: Denys Date: Wed, 4 Sep 2024 19:27:53 +0300 Subject: [PATCH 10/21] Add some files --- readme.md | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/readme.md b/readme.md index c9ef08e..fcd66c9 100644 --- a/readme.md +++ b/readme.md @@ -1,19 +1,17 @@ -Commands: +### Commands: --e Encrypt --d Decrypt --bf Brute force -Arguments: +- e Encrypt +- d Decrypt +- bf Brute force --k Key --f File path +### Arguments: -Example: +- You need to write the arguments in the order: encrypt/decrypt/bruteforce(e,d,bf) + key(1 or -1 and further in decreasing, increasing order) + file path. + In the case of bruteforce, a key is not needed. --e -k 1 -f "/path/to/file.txt" - Encrypt file with key 1 --d -k 5 -f "/path/to/file [ENCRYPTED].txt" - Decrypt file with key 5 --bf -f "/path/to/file [ENCRYPTED].txt" - Brute force decrypt file +### Example: -Argument could be in any order +- e 1 "/path/to/file.txt" - Encrypt file with key 1 +- d 5 "/path/to/file [ENCRYPTED].txt" - Decrypt file with key 5 +- bf "/path/to/file [ENCRYPTED].txt" - Brute force decrypt file --e -f "/path/to/file.txt" -k 1 \ No newline at end of file From 7fba6687c0b55a535545289823fe47c3928202b8 Mon Sep 17 00:00:00 2001 From: Denys Date: Wed, 4 Sep 2024 19:39:24 +0300 Subject: [PATCH 11/21] Add some files --- .../java/ua/com/javarush/gnew/crypt/code/Cryptanalyzer.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/java/ua/com/javarush/gnew/crypt/code/Cryptanalyzer.java b/src/main/java/ua/com/javarush/gnew/crypt/code/Cryptanalyzer.java index b186247..9cbb694 100644 --- a/src/main/java/ua/com/javarush/gnew/crypt/code/Cryptanalyzer.java +++ b/src/main/java/ua/com/javarush/gnew/crypt/code/Cryptanalyzer.java @@ -34,9 +34,7 @@ public String encryption(String str, int key){ }else{ builder.append(symbol); } - } - return builder.toString(); } public String decryption(String str, int key) { @@ -54,7 +52,6 @@ public String decryption(String str, int key) { builder.append(encrypted); continue; } - int GettingIndex = UKR.indexOf(symbol); if (GettingIndex != -1) { Character encrypted = UKR_MOD.get(GettingIndex); From 77d86d326050e28c6de06ed4130f4cc636e8c72d Mon Sep 17 00:00:00 2001 From: Denys Date: Wed, 4 Sep 2024 19:39:44 +0300 Subject: [PATCH 12/21] Add some files --- .../java/ua/com/javarush/gnew/crypt/code/Cryptanalyzer.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/ua/com/javarush/gnew/crypt/code/Cryptanalyzer.java b/src/main/java/ua/com/javarush/gnew/crypt/code/Cryptanalyzer.java index 9cbb694..2121f6e 100644 --- a/src/main/java/ua/com/javarush/gnew/crypt/code/Cryptanalyzer.java +++ b/src/main/java/ua/com/javarush/gnew/crypt/code/Cryptanalyzer.java @@ -1,7 +1,5 @@ package ua.com.javarush.gnew.crypt.code; -import ua.com.javarush.gnew.Constants.Constants; - import java.util.ArrayList; import java.util.Collections; From 3b127864c50c6c363ab2b3d31fb7ecd1d0998035 Mon Sep 17 00:00:00 2001 From: Denys Date: Thu, 5 Sep 2024 21:47:25 +0300 Subject: [PATCH 13/21] Add some files --- readme.md | 26 ++++++-- src/main/java/ua/com/javarush/gnew/Main.java | 2 +- .../javarush/gnew/runner/ArgumentsParser.java | 66 ++++++++++++------- .../java/ua/com/javarush/gnew/MainTest.java | 12 ++-- src/test/resources/test.txt | 6 +- 5 files changed, 74 insertions(+), 38 deletions(-) diff --git a/readme.md b/readme.md index fcd66c9..586b8e4 100644 --- a/readme.md +++ b/readme.md @@ -1,8 +1,22 @@ +### Notes: +- This Cypher can ENCRYPT or DECRYPT your sentences. +- You can found correct texts or sentences by using this program. +- You can decrypt or encrypt text by using CESAR CYPHER. +- Support for UKRAINIAN and ENGLISH languages in encryption, decryption, and also in brute force + +### Last Upgrades: +- We have an automatic program that can obtain decrypted text without a key. +- The program now takes into account spaces in the specified parameters. +- Some bug fixed. + +### Brute force +- Сan automatically decrypt any text (Caesar cipher) and find the correct key. + ### Commands: -- e Encrypt -- d Decrypt -- bf Brute force +- -e Encrypt +- -d Decrypt +- -bf Brute force ### Arguments: @@ -11,7 +25,7 @@ ### Example: -- e 1 "/path/to/file.txt" - Encrypt file with key 1 -- d 5 "/path/to/file [ENCRYPTED].txt" - Decrypt file with key 5 -- bf "/path/to/file [ENCRYPTED].txt" - Brute force decrypt file +- -e -k 1 -f "/path/to/file.txt" - Encrypt file with key 1 +- -d -k 5 -f "/path/to/file [ENCRYPTED].txt" - Decrypt file with key 5 +- -bf -f "/path/to/file [ENCRYPTED].txt" - Brute force decrypt file diff --git a/src/main/java/ua/com/javarush/gnew/Main.java b/src/main/java/ua/com/javarush/gnew/Main.java index b8dbd6a..0a13809 100644 --- a/src/main/java/ua/com/javarush/gnew/Main.java +++ b/src/main/java/ua/com/javarush/gnew/Main.java @@ -20,7 +20,7 @@ public static void main(String[] args) { RunBruteforce runBruteforce = new RunBruteforce(); FileManager fileManager = new FileManager(); ArgumentsParser argumentsParser = new ArgumentsParser(); - RunOptions runOptions = argumentsParser.parse(); + RunOptions runOptions = argumentsParser.parse(args); try { if (runOptions.getCommand() == Command.ENCRYPT) { String content = fileManager.read(runOptions.getFilePath()); diff --git a/src/main/java/ua/com/javarush/gnew/runner/ArgumentsParser.java b/src/main/java/ua/com/javarush/gnew/runner/ArgumentsParser.java index 040e56b..7b505ab 100644 --- a/src/main/java/ua/com/javarush/gnew/runner/ArgumentsParser.java +++ b/src/main/java/ua/com/javarush/gnew/runner/ArgumentsParser.java @@ -1,39 +1,57 @@ package ua.com.javarush.gnew.runner; import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Scanner; + public class ArgumentsParser { - public RunOptions parse() { - Scanner input = new Scanner(System.in); - Command command; + public RunOptions parse(String[] args) { + Command command = null; Integer key = null; - Path filePath ; - - System.out.println("Введите команду (e - encrypt, d - decrypt, bf - bruteforce):"); - String commandInput = input.nextLine().trim(); - - if (commandInput.equalsIgnoreCase("e")) { - command = Command.ENCRYPT; - } else if (commandInput.equalsIgnoreCase("d")) { - command = Command.DECRYPT; - } else if (commandInput.equalsIgnoreCase("bf")) { - command = Command.BRUTEFORCE; - } else { - throw new IllegalArgumentException("Неизвестная команда. Ожидалась команда (e, d, или bf)"); + Path filePath = null; + + for (int i = 0; i < args.length; i++) { + String arg = args[i]; + + if (arg.equalsIgnoreCase("-e")) { + command = Command.ENCRYPT; + } else if (arg.equalsIgnoreCase("-d")) { + command = Command.DECRYPT; + } else if (arg.equalsIgnoreCase("-bf")) { + command = Command.BRUTEFORCE; + } else if (arg.equalsIgnoreCase("-k")){ + //throw new IllegalArgumentException("Command (e, d, or bf) is required"); + if (i + 1 < args.length) { + key = Integer.parseInt(args[++i]); + } else { + throw new IllegalArgumentException("Missing value for key"); + } + }else if(arg.equalsIgnoreCase("-f")){ + if (i + 1 < args.length) { + StringBuilder filePathBuilder = new StringBuilder(args[++i]); + + while (i + 1 < args.length && !args[i + 1].startsWith("-")) { + filePathBuilder.append(" ").append(args[++i]); + } + filePath = Path.of(filePathBuilder.toString()); + } else { + throw new IllegalArgumentException("Missing value for file"); + } + } else { + throw new IllegalArgumentException("Unknown argument: " + arg); + } } if (command == Command.ENCRYPT || command == Command.DECRYPT) { - System.out.println("Введите ключ для шифрования/дешифрования:"); - key = Integer.parseInt(input.nextLine().trim()); + if (key == null) { + throw new IllegalArgumentException("Key is required for encrypt or decrypt mode"); + } } - System.out.println("Введите путь к файлу:"); - String filePathInput = input.nextLine().trim(); - filePath = Paths.get(filePathInput); - + if (filePath == null) { + throw new IllegalArgumentException("File path is required"); + } return new RunOptions(command, key, filePath); } } + diff --git a/src/test/java/ua/com/javarush/gnew/MainTest.java b/src/test/java/ua/com/javarush/gnew/MainTest.java index 0b54d30..b7f6356 100644 --- a/src/test/java/ua/com/javarush/gnew/MainTest.java +++ b/src/test/java/ua/com/javarush/gnew/MainTest.java @@ -15,10 +15,10 @@ import static org.junit.jupiter.api.Assertions.*; class MainTest { - private static final boolean UKRAINIAN_LANGUAGE_TEST = true; - private static final String ENCRYPT_COMMAND = "e"; - private static final String DECRYPT_COMMAND = "d"; - private static final String BF_COMMAND = "bf"; + private static final boolean UKRAINIAN_LANGUAGE_TEST = false; + private static final String ENCRYPT_COMMAND = "-e"; + private static final String DECRYPT_COMMAND = "-d"; + private static final String BF_COMMAND = "-bf"; private static final String HAMLET_EN = """ THE TRAGEDY OF HAMLET, PRINCE OF DENMARK @@ -112,7 +112,7 @@ private Path createTestFile(String fileName, String content) throws IOException private Path execute(String command, Path inputFilePath, int key) { List filesBefore = listFiles(tempDir); - List params = List.of(command, "k", String.valueOf(key), "f", inputFilePath.toString()); + List params = List.of(command, "-k", String.valueOf(key), "-f", inputFilePath.toString()); try { Main.main(params.toArray(new String[0])); @@ -343,7 +343,7 @@ void negativeKeyEncryption(String input, int key, String expected) throws IOExce void fileNotExists() { Path fakeFilePath = Path.of("/fake/path/file.txt"); - String[] params = {ENCRYPT_COMMAND, "f", fakeFilePath.toString(), "k", "5"}; + String[] params = {ENCRYPT_COMMAND, "-f", fakeFilePath.toString(), "-k", "5"}; assertDoesNotThrow(() -> Main.main(params), "Exception was thrown while processing a non-existent file path."); } diff --git a/src/test/resources/test.txt b/src/test/resources/test.txt index 6769dd6..06bd427 100644 --- a/src/test/resources/test.txt +++ b/src/test/resources/test.txt @@ -1 +1,5 @@ -Hello world! \ No newline at end of file +To be, or not to be: that is the question: +Whether ’tis nobler in the mind to suffer +The slings and arrows of outrageous fortune, +Or to take arms against a sea of troubles, +And by opposing end them? To die: to sleep; \ No newline at end of file From 1fe79dc619e81f451a599dc6166c07453fe6a3f2 Mon Sep 17 00:00:00 2001 From: Denys Date: Thu, 5 Sep 2024 22:15:20 +0300 Subject: [PATCH 14/21] Upgrd UKR lang --- .../gnew/crypt/code/RunBruteforce.java | 176 ++++++++++++------ .../java/ua/com/javarush/gnew/MainTest.java | 2 +- src/test/resources/test.UKR.txt | 31 +++ 3 files changed, 150 insertions(+), 59 deletions(-) create mode 100644 src/test/resources/test.UKR.txt diff --git a/src/main/java/ua/com/javarush/gnew/crypt/code/RunBruteforce.java b/src/main/java/ua/com/javarush/gnew/crypt/code/RunBruteforce.java index c5e4117..68b041d 100644 --- a/src/main/java/ua/com/javarush/gnew/crypt/code/RunBruteforce.java +++ b/src/main/java/ua/com/javarush/gnew/crypt/code/RunBruteforce.java @@ -4,73 +4,133 @@ import java.util.Collections; import static ua.com.javarush.gnew.Constants.Constants.ENG; +import static ua.com.javarush.gnew.Constants.Constants.UKR; - public class RunBruteforce { - public String bruteforce(String str, String[] dictionary, String[] dictionaryUKR) { - char[] array = str.toCharArray(); - String bestMatch = null; - int maxMatches = 0; - for (int key = 0; key < ENG.size(); key++) { - ArrayList ENG_MOD = new ArrayList<>(ENG); - Collections.rotate(ENG_MOD, key); - StringBuilder builder = new StringBuilder(); - for (char symbol : array) { - int originalIndex = ENG.indexOf(symbol); - if (originalIndex != -1) { - Character encrypted = ENG_MOD.get(originalIndex); - builder.append(encrypted); - } else { - builder.append(symbol); - } - } - String DecryptedText = builder.toString(); - int matches = 0; - for (String words : dictionary) { - if (DecryptedText.contains(words)) { - matches++; - } - } - //System.out.println("Key: " + key + " DecryptedText: " + DecryptedText + " Matches: " + matches); - if (matches > maxMatches) { - maxMatches = matches; - bestMatch = DecryptedText; +public class RunBruteforce { + + public String bruteforce(String str, String[] dictionary, String[] dictionaryUKR) { + char[] array = str.toCharArray(); + String bestMatch = null; + int maxMatches = 0; + + for (int key = 0; key < ENG.size(); key++) { + ArrayList ENG_MOD = new ArrayList<>(ENG); + Collections.rotate(ENG_MOD, key); + StringBuilder builder = new StringBuilder(); + + for (char symbol : array) { + int originalIndex = ENG.indexOf(symbol); + if (originalIndex != -1) { + Character decrypted = ENG_MOD.get(originalIndex); + builder.append(decrypted); + } else { + builder.append(symbol); } } - return bestMatch != null ? bestMatch : "Брутфорс не дал результатов."; + + String DecryptedText = builder.toString(); + int matches = countMatches(DecryptedText, dictionary); + + if (matches > maxMatches) { + maxMatches = matches; + bestMatch = DecryptedText; + } } - public String getKey(String str, String[] dictionary, String[] dictionaryUKR) { - - char[] array = str.toCharArray(); - int maxMatches = 0; - String KeyResult = null; - for (int key = 0; key < ENG.size(); key++) { - ArrayList ENG_MOD = new ArrayList<>(ENG); - Collections.rotate(ENG_MOD, key); - StringBuilder builder = new StringBuilder(); - for (char symbol : array) { - int originalIndex = ENG.indexOf(symbol); - if (originalIndex != -1) { - Character encrypted = ENG_MOD.get(originalIndex); - builder.append(encrypted); - } else { - builder.append(symbol); - } + + + for (int key = 0; key < UKR.size(); key++) { + ArrayList UKR_MOD = new ArrayList<>(UKR); + Collections.rotate(UKR_MOD, key); + StringBuilder builder = new StringBuilder(); + + for (char symbol : array) { + int originalIndex = UKR.indexOf(symbol); + if (originalIndex != -1) { + Character decrypted = UKR_MOD.get(originalIndex); + builder.append(decrypted); + } else { + builder.append(symbol); } - String DecryptedText = builder.toString(); - int matches = 0; - for (String words : dictionary) { - if (DecryptedText.contains(words)) { - matches++; - } + } + + String DecryptedText = builder.toString(); + int matches = countMatches(DecryptedText, dictionaryUKR); + + if (matches > maxMatches) { + maxMatches = matches; + bestMatch = DecryptedText; + } + } + + return bestMatch != null ? bestMatch : "Брутфорс не дал результатов."; + } + + + public String getKey(String str, String[] dictionary, String[] dictionaryUKR) { + char[] array = str.toCharArray(); + int maxMatches = 0; + String KeyResult = null; + + for (int key = 0; key < ENG.size(); key++) { + ArrayList ENG_MOD = new ArrayList<>(ENG); + Collections.rotate(ENG_MOD, key); + StringBuilder builder = new StringBuilder(); + + for (char symbol : array) { + int originalIndex = ENG.indexOf(symbol); + if (originalIndex != -1) { + Character decrypted = ENG_MOD.get(originalIndex); + builder.append(decrypted); + } else { + builder.append(symbol); } - //System.out.println("Key: " + key + " DecryptedText: " + DecryptedText + " Matches: " + matches); + } + + String DecryptedText = builder.toString(); + int matches = countMatches(DecryptedText, dictionary); + + if (matches > maxMatches) { + maxMatches = matches; + KeyResult = "Key: " + key + " (ENG)"; + } + } + - if (matches > maxMatches) { - maxMatches = matches; - KeyResult = "Key: " + key; + for (int key = 0; key < UKR.size(); key++) { + ArrayList UKR_MOD = new ArrayList<>(UKR); + Collections.rotate(UKR_MOD, key); + StringBuilder builder = new StringBuilder(); + + for (char symbol : array) { + int originalIndex = UKR.indexOf(symbol); + if (originalIndex != -1) { + Character decrypted = UKR_MOD.get(originalIndex); + builder.append(decrypted); + } else { + builder.append(symbol); } } - return KeyResult; + + String DecryptedText = builder.toString(); + int matches = countMatches(DecryptedText, dictionaryUKR); + + if (matches > maxMatches) { + maxMatches = matches; + KeyResult = "Key: " + key + " (UKR)"; + } } + + return KeyResult; } + + private int countMatches(String text, String[] dictionary) { + int matches = 0; + for (String word : dictionary) { + if (text.contains(word)) { + matches++; + } + } + return matches; + } +} diff --git a/src/test/java/ua/com/javarush/gnew/MainTest.java b/src/test/java/ua/com/javarush/gnew/MainTest.java index b7f6356..89d57f6 100644 --- a/src/test/java/ua/com/javarush/gnew/MainTest.java +++ b/src/test/java/ua/com/javarush/gnew/MainTest.java @@ -15,7 +15,7 @@ import static org.junit.jupiter.api.Assertions.*; class MainTest { - private static final boolean UKRAINIAN_LANGUAGE_TEST = false; + private static final boolean UKRAINIAN_LANGUAGE_TEST = true; private static final String ENCRYPT_COMMAND = "-e"; private static final String DECRYPT_COMMAND = "-d"; private static final String BF_COMMAND = "-bf"; diff --git a/src/test/resources/test.UKR.txt b/src/test/resources/test.UKR.txt new file mode 100644 index 0000000..849f527 --- /dev/null +++ b/src/test/resources/test.UKR.txt @@ -0,0 +1,31 @@ +Стояла ясна та прохолодна квітнева днина, на годинниках пробило тринадцяту годину. + Вінстон Сміт, притискуючи підборіддя до грудей щоб сховатися від підступного вітру, + швидко ковзнув крізь скляні двері великого панельного будинку що звався "Перемога", + але не достатньо швидко щоб завадити вихру з піску та пилюки увійти разом з ним. + + У вестибюлі тхнуло вареною капустою та старими драними килимками. В одному з його + кінців був кольоровий плакат, завеликий щоб розташувати його всередині квартири, + прибитий кнопками до стіни. На ньому було зображено лише величезне обличчя, + більш ніж метр завширшки : обличчя чоловіка приблизно сорока п'яти років, + з масивними чорними вусами та привабливо суворими та прямими рисами обличчя. + Вінстон пішов сходами. Не було сенсу намагатися піднятися ліфтом. Навіть у + найкращі часи він працював лише зрідка, а відтепер черговий електрик вимикав + його взагалі під час світлого часу доби. Це була частина політики заощадження + під час приготування до Тижня Ненависті. Квартира знаходилася на сьомому поверсі, + і Вінстон, який мав тридцять дев'ять років та варикозну виразку на правій + щиколотці, йшов дуже повільно, відпочиваючи по декілька разів під час сходження. + На кожному поверсі, навпроти ліфтової шахти, зі стіни пильно дивився плакат з + величезним обличчям. Це було одне з тих зображень,які створені так щоб очі + невідривно слідкували за тобою куди б ти не пішов. СТАРШИЙ БРАТ НАГЛЯДАЄ ЗА ТОБОЮ, + промовляв напис під зображенням. + + Всередині квартири солодкий та принадний голос диктував перелік цифр, що якось + стосувалися виробництва чушкового чавуну. Цей голос лунав з видовженої металевої + тарелі, що нагадувала поблякле дзеркало, та була вмонтована в поверхню стіни праворуч. + Вінстон повернув вимикача і голос дещо вщух, одначе слова що лунали ще можна було + розібрати. Цей прилад (який звався телезахист) можна було приглушити, але не було + жодного способу вимкнути його повністю. Він підійшов до вікна : маленька, квола + фігурка, його худорлявого тіла лише підкреслювалась блакитним спецодягом, + що був уніформою його партії. Його волосся було яскраво світлим, його обличчя бул + природньо рум'яним та життєрадісним, його шкіра була огрубілою від господарчого + мила та тупого леза бритви, та вкрите крижаною маскою зими яка щойно скінчилася. \ No newline at end of file From a9a7d5734f031d278668c53b4a5f08a454698e7d Mon Sep 17 00:00:00 2001 From: Denys Date: Fri, 6 Sep 2024 03:19:01 +0300 Subject: [PATCH 15/21] Upgrd UKR lang --- .../javarush/gnew/Constants/Constants.java | 10 +- .../gnew/crypt/code/Cryptanalyzer.java | 113 +++++++++++----- .../gnew/crypt/code/RunBruteforce.java | 125 +++++++++++++----- .../javarush/gnew/runner/ArgumentsParser.java | 1 - src/test/resources/test.UKR.txt | 31 ----- src/test/resources/test.txt | 36 ++++- 6 files changed, 212 insertions(+), 104 deletions(-) delete mode 100644 src/test/resources/test.UKR.txt diff --git a/src/main/java/ua/com/javarush/gnew/Constants/Constants.java b/src/main/java/ua/com/javarush/gnew/Constants/Constants.java index 4ceeec7..aa7a999 100644 --- a/src/main/java/ua/com/javarush/gnew/Constants/Constants.java +++ b/src/main/java/ua/com/javarush/gnew/Constants/Constants.java @@ -4,11 +4,13 @@ import java.util.Arrays; public class Constants { - public static final ArrayList ENG = new ArrayList<>(Arrays.asList( - 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + public static final ArrayList ENG_LOWER = new ArrayList<>(Arrays.asList( + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z')); + public static final ArrayList ENG_UPPER = new ArrayList<>(Arrays.asList( 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z')); - public static final ArrayList UKR = new ArrayList<>(Arrays.asList( - 'а', 'б', 'в', 'г', 'ґ', 'д', 'е', 'є', 'ж', 'з', 'и', 'і', 'ї', 'й', 'к', 'л', 'м', 'н', 'о', 'п', 'р', 'с', 'т', 'у', 'ф', 'х', 'ц', 'ч', 'ш', 'щ', 'ь', 'ю', 'я', + public static final ArrayList UKR_LOWER = new ArrayList<>(Arrays.asList( + 'а', 'б', 'в', 'г', 'ґ', 'д', 'е', 'є', 'ж', 'з', 'и', 'і', 'ї', 'й', 'к', 'л', 'м', 'н', 'о', 'п', 'р', 'с', 'т', 'у', 'ф', 'х', 'ц', 'ч', 'ш', 'щ', 'ь', 'ю', 'я')); + public static final ArrayList UKR_UPPER = new ArrayList<>(Arrays.asList( 'А', 'Б', 'В', 'Г', 'Ґ', 'Д', 'Е', 'Є', 'Ж', 'З', 'И', 'І', 'Ї', 'Й', 'К', 'Л', 'М', 'Н', 'О', 'П', 'Р', 'С', 'Т', 'У', 'Ф', 'Х', 'Ц', 'Ч', 'Ш', 'Щ', 'Ь', 'Ю', 'Я')); } diff --git a/src/main/java/ua/com/javarush/gnew/crypt/code/Cryptanalyzer.java b/src/main/java/ua/com/javarush/gnew/crypt/code/Cryptanalyzer.java index 2121f6e..4afbf87 100644 --- a/src/main/java/ua/com/javarush/gnew/crypt/code/Cryptanalyzer.java +++ b/src/main/java/ua/com/javarush/gnew/crypt/code/Cryptanalyzer.java @@ -3,57 +3,110 @@ import java.util.ArrayList; import java.util.Collections; -import static ua.com.javarush.gnew.Constants.Constants.ENG; -import static ua.com.javarush.gnew.Constants.Constants.UKR; +import static ua.com.javarush.gnew.Constants.Constants.*; public class Cryptanalyzer { - public String encryption(String str, int key){ + public String encryption(String str, int key) { key = Math.negateExact(key); - ArrayList ENG_MOD = new ArrayList<>(ENG); - ArrayList UKR_MOD = new ArrayList<>(UKR); - Collections.rotate(ENG_MOD, key); - Collections.rotate(UKR_MOD, key); + ArrayList ENG_LOWER_MOD = new ArrayList<>(ENG_LOWER); + ArrayList UKR_LOWER_MOD = new ArrayList<>(UKR_LOWER); + Collections.rotate(ENG_LOWER_MOD, key); + Collections.rotate(UKR_LOWER_MOD, key); + + ArrayList ENG_UPPER_MOD = new ArrayList<>(ENG_UPPER); + ArrayList UKR_UPPER_MOD = new ArrayList<>(UKR_UPPER); + Collections.rotate(ENG_UPPER_MOD, key); + Collections.rotate(UKR_UPPER_MOD, key); + char[] array = str.toCharArray(); StringBuilder builder = new StringBuilder(); for (char symbol : array) { - int originalIndex = ENG.indexOf(symbol); - if (originalIndex != -1) { - Character encrypted = ENG_MOD.get(originalIndex); - builder.append(encrypted); - continue; + if (Character.isLowerCase(symbol)) { + int originalIndex = ENG_LOWER.indexOf(symbol); + if (originalIndex != -1) { + Character encrypted = ENG_LOWER_MOD.get(originalIndex); + builder.append(encrypted); + continue; + } + + originalIndex = UKR_LOWER.indexOf(symbol); + if (originalIndex != -1) { + Character encrypted = UKR_LOWER_MOD.get(originalIndex); + builder.append(encrypted); + } else { + builder.append(symbol); + } } + else if (Character.isUpperCase(symbol)) { + int originalIndex = ENG_UPPER.indexOf(symbol); + if (originalIndex != -1) { + Character encrypted = ENG_UPPER_MOD.get(originalIndex); + builder.append(encrypted); + continue; + } - int GettingIndex = UKR.indexOf(symbol); - if (GettingIndex != -1) { - Character encrypted = UKR_MOD.get(GettingIndex); - builder.append(encrypted); - }else{ + originalIndex = UKR_UPPER.indexOf(symbol); + if (originalIndex != -1) { + Character encrypted = UKR_UPPER_MOD.get(originalIndex); + builder.append(encrypted); + } else { + builder.append(symbol); + } + } else { builder.append(symbol); } } return builder.toString(); } + public String decryption(String str, int key) { - ArrayList ENG_MOD = new ArrayList<>(ENG); - ArrayList UKR_MOD = new ArrayList<>(UKR); - Collections.rotate(ENG_MOD, key); - Collections.rotate(UKR_MOD, key); + ArrayList ENG_LOWER_MOD = new ArrayList<>(ENG_LOWER); + ArrayList UKR_LOWER_MOD = new ArrayList<>(UKR_LOWER); + Collections.rotate(ENG_LOWER_MOD, key); + Collections.rotate(UKR_LOWER_MOD, key); + + ArrayList ENG_UPPER_MOD = new ArrayList<>(ENG_UPPER); + ArrayList UKR_UPPER_MOD = new ArrayList<>(UKR_UPPER); + Collections.rotate(ENG_UPPER_MOD, key); + Collections.rotate(UKR_UPPER_MOD, key); + char[] array = str.toCharArray(); StringBuilder builder = new StringBuilder(); for (char symbol : array) { - int originalIndex = ENG.indexOf(symbol); - if (originalIndex != -1) { - Character encrypted = ENG_MOD.get(originalIndex); - builder.append(encrypted); - continue; + if (Character.isLowerCase(symbol)) { + int originalIndex = ENG_LOWER.indexOf(symbol); + if (originalIndex != -1) { + Character decrypted = ENG_LOWER_MOD.get(originalIndex); + builder.append(decrypted); + continue; + } + + originalIndex = UKR_LOWER.indexOf(symbol); + if (originalIndex != -1) { + Character decrypted = UKR_LOWER_MOD.get(originalIndex); + builder.append(decrypted); + } else { + builder.append(symbol); + } } - int GettingIndex = UKR.indexOf(symbol); - if (GettingIndex != -1) { - Character encrypted = UKR_MOD.get(GettingIndex); - builder.append(encrypted); + else if (Character.isUpperCase(symbol)) { + int originalIndex = ENG_UPPER.indexOf(symbol); + if (originalIndex != -1) { + Character decrypted = ENG_UPPER_MOD.get(originalIndex); + builder.append(decrypted); + continue; + } + + originalIndex = UKR_UPPER.indexOf(symbol); + if (originalIndex != -1) { + Character decrypted = UKR_UPPER_MOD.get(originalIndex); + builder.append(decrypted); + } else { + builder.append(symbol); + } } else { builder.append(symbol); } diff --git a/src/main/java/ua/com/javarush/gnew/crypt/code/RunBruteforce.java b/src/main/java/ua/com/javarush/gnew/crypt/code/RunBruteforce.java index 68b041d..8c93141 100644 --- a/src/main/java/ua/com/javarush/gnew/crypt/code/RunBruteforce.java +++ b/src/main/java/ua/com/javarush/gnew/crypt/code/RunBruteforce.java @@ -3,26 +3,40 @@ import java.util.ArrayList; import java.util.Collections; -import static ua.com.javarush.gnew.Constants.Constants.ENG; -import static ua.com.javarush.gnew.Constants.Constants.UKR; +import static ua.com.javarush.gnew.Constants.Constants.*; public class RunBruteforce { - public String bruteforce(String str, String[] dictionary, String[] dictionaryUKR) { char[] array = str.toCharArray(); String bestMatch = null; int maxMatches = 0; - for (int key = 0; key < ENG.size(); key++) { - ArrayList ENG_MOD = new ArrayList<>(ENG); - Collections.rotate(ENG_MOD, key); + for (int key = 0; key < ENG_LOWER.size(); key++) { + + ArrayList ENG_LOWER_MOD = new ArrayList<>(ENG_LOWER); + Collections.rotate(ENG_LOWER_MOD, key); + ArrayList ENG_UPPER_MOD = new ArrayList<>(ENG_UPPER); + Collections.rotate(ENG_UPPER_MOD, key); + StringBuilder builder = new StringBuilder(); for (char symbol : array) { - int originalIndex = ENG.indexOf(symbol); - if (originalIndex != -1) { - Character decrypted = ENG_MOD.get(originalIndex); - builder.append(decrypted); + if (Character.isLowerCase(symbol)) { + int originalIndex = ENG_LOWER.indexOf(symbol); + if (originalIndex != -1) { + Character decrypted = ENG_LOWER_MOD.get(originalIndex); + builder.append(decrypted); + } else { + builder.append(symbol); + } + } else if (Character.isUpperCase(symbol)) { + int originalIndex = ENG_UPPER.indexOf(symbol); + if (originalIndex != -1) { + Character decrypted = ENG_UPPER_MOD.get(originalIndex); + builder.append(decrypted); + } else { + builder.append(symbol); + } } else { builder.append(symbol); } @@ -36,18 +50,33 @@ public String bruteforce(String str, String[] dictionary, String[] dictionaryUKR bestMatch = DecryptedText; } } + for (int key = 0; key < UKR_LOWER.size(); key++) { + ArrayList UKR_LOWER_MOD = new ArrayList<>(UKR_LOWER); + Collections.rotate(UKR_LOWER_MOD, key); + + ArrayList UKR_UPPER_MOD = new ArrayList<>(UKR_UPPER); + Collections.rotate(UKR_UPPER_MOD, key); - for (int key = 0; key < UKR.size(); key++) { - ArrayList UKR_MOD = new ArrayList<>(UKR); - Collections.rotate(UKR_MOD, key); StringBuilder builder = new StringBuilder(); for (char symbol : array) { - int originalIndex = UKR.indexOf(symbol); - if (originalIndex != -1) { - Character decrypted = UKR_MOD.get(originalIndex); - builder.append(decrypted); + if (Character.isLowerCase(symbol)) { + int originalIndex = UKR_LOWER.indexOf(symbol); + if (originalIndex != -1) { + Character decrypted = UKR_LOWER_MOD.get(originalIndex); + builder.append(decrypted); + } else { + builder.append(symbol); + } + } else if (Character.isUpperCase(symbol)) { + int originalIndex = UKR_UPPER.indexOf(symbol); + if (originalIndex != -1) { + Character decrypted = UKR_UPPER_MOD.get(originalIndex); + builder.append(decrypted); + } else { + builder.append(symbol); + } } else { builder.append(symbol); } @@ -65,22 +94,37 @@ public String bruteforce(String str, String[] dictionary, String[] dictionaryUKR return bestMatch != null ? bestMatch : "Брутфорс не дал результатов."; } - public String getKey(String str, String[] dictionary, String[] dictionaryUKR) { char[] array = str.toCharArray(); int maxMatches = 0; String KeyResult = null; - for (int key = 0; key < ENG.size(); key++) { - ArrayList ENG_MOD = new ArrayList<>(ENG); - Collections.rotate(ENG_MOD, key); + for (int key = 0; key < ENG_LOWER.size(); key++) { + ArrayList ENG_LOWER_MOD = new ArrayList<>(ENG_LOWER); + Collections.rotate(ENG_LOWER_MOD, key); + + ArrayList ENG_UPPER_MOD = new ArrayList<>(ENG_UPPER); + Collections.rotate(ENG_UPPER_MOD, key); + StringBuilder builder = new StringBuilder(); for (char symbol : array) { - int originalIndex = ENG.indexOf(symbol); - if (originalIndex != -1) { - Character decrypted = ENG_MOD.get(originalIndex); - builder.append(decrypted); + if (Character.isLowerCase(symbol)) { + int originalIndex = ENG_LOWER.indexOf(symbol); + if (originalIndex != -1) { + Character decrypted = ENG_LOWER_MOD.get(originalIndex); + builder.append(decrypted); + } else { + builder.append(symbol); + } + } else if (Character.isUpperCase(symbol)) { + int originalIndex = ENG_UPPER.indexOf(symbol); + if (originalIndex != -1) { + Character decrypted = ENG_UPPER_MOD.get(originalIndex); + builder.append(decrypted); + } else { + builder.append(symbol); + } } else { builder.append(symbol); } @@ -95,17 +139,32 @@ public String getKey(String str, String[] dictionary, String[] dictionaryUKR) { } } + for (int key = 0; key < UKR_LOWER.size(); key++) { + ArrayList UKR_LOWER_MOD = new ArrayList<>(UKR_LOWER); + Collections.rotate(UKR_LOWER_MOD, key); + + ArrayList UKR_UPPER_MOD = new ArrayList<>(UKR_UPPER); + Collections.rotate(UKR_UPPER_MOD, key); - for (int key = 0; key < UKR.size(); key++) { - ArrayList UKR_MOD = new ArrayList<>(UKR); - Collections.rotate(UKR_MOD, key); StringBuilder builder = new StringBuilder(); for (char symbol : array) { - int originalIndex = UKR.indexOf(symbol); - if (originalIndex != -1) { - Character decrypted = UKR_MOD.get(originalIndex); - builder.append(decrypted); + if (Character.isLowerCase(symbol)) { + int originalIndex = UKR_LOWER.indexOf(symbol); + if (originalIndex != -1) { + Character decrypted = UKR_LOWER_MOD.get(originalIndex); + builder.append(decrypted); + } else { + builder.append(symbol); + } + } else if (Character.isUpperCase(symbol)) { + int originalIndex = UKR_UPPER.indexOf(symbol); + if (originalIndex != -1) { + Character decrypted = UKR_UPPER_MOD.get(originalIndex); + builder.append(decrypted); + } else { + builder.append(symbol); + } } else { builder.append(symbol); } @@ -123,7 +182,6 @@ public String getKey(String str, String[] dictionary, String[] dictionaryUKR) { return KeyResult; } - private int countMatches(String text, String[] dictionary) { int matches = 0; for (String word : dictionary) { @@ -134,3 +192,4 @@ private int countMatches(String text, String[] dictionary) { return matches; } } + diff --git a/src/main/java/ua/com/javarush/gnew/runner/ArgumentsParser.java b/src/main/java/ua/com/javarush/gnew/runner/ArgumentsParser.java index 7b505ab..d255b75 100644 --- a/src/main/java/ua/com/javarush/gnew/runner/ArgumentsParser.java +++ b/src/main/java/ua/com/javarush/gnew/runner/ArgumentsParser.java @@ -19,7 +19,6 @@ public RunOptions parse(String[] args) { } else if (arg.equalsIgnoreCase("-bf")) { command = Command.BRUTEFORCE; } else if (arg.equalsIgnoreCase("-k")){ - //throw new IllegalArgumentException("Command (e, d, or bf) is required"); if (i + 1 < args.length) { key = Integer.parseInt(args[++i]); } else { diff --git a/src/test/resources/test.UKR.txt b/src/test/resources/test.UKR.txt deleted file mode 100644 index 849f527..0000000 --- a/src/test/resources/test.UKR.txt +++ /dev/null @@ -1,31 +0,0 @@ -Стояла ясна та прохолодна квітнева днина, на годинниках пробило тринадцяту годину. - Вінстон Сміт, притискуючи підборіддя до грудей щоб сховатися від підступного вітру, - швидко ковзнув крізь скляні двері великого панельного будинку що звався "Перемога", - але не достатньо швидко щоб завадити вихру з піску та пилюки увійти разом з ним. - - У вестибюлі тхнуло вареною капустою та старими драними килимками. В одному з його - кінців був кольоровий плакат, завеликий щоб розташувати його всередині квартири, - прибитий кнопками до стіни. На ньому було зображено лише величезне обличчя, - більш ніж метр завширшки : обличчя чоловіка приблизно сорока п'яти років, - з масивними чорними вусами та привабливо суворими та прямими рисами обличчя. - Вінстон пішов сходами. Не було сенсу намагатися піднятися ліфтом. Навіть у - найкращі часи він працював лише зрідка, а відтепер черговий електрик вимикав - його взагалі під час світлого часу доби. Це була частина політики заощадження - під час приготування до Тижня Ненависті. Квартира знаходилася на сьомому поверсі, - і Вінстон, який мав тридцять дев'ять років та варикозну виразку на правій - щиколотці, йшов дуже повільно, відпочиваючи по декілька разів під час сходження. - На кожному поверсі, навпроти ліфтової шахти, зі стіни пильно дивився плакат з - величезним обличчям. Це було одне з тих зображень,які створені так щоб очі - невідривно слідкували за тобою куди б ти не пішов. СТАРШИЙ БРАТ НАГЛЯДАЄ ЗА ТОБОЮ, - промовляв напис під зображенням. - - Всередині квартири солодкий та принадний голос диктував перелік цифр, що якось - стосувалися виробництва чушкового чавуну. Цей голос лунав з видовженої металевої - тарелі, що нагадувала поблякле дзеркало, та була вмонтована в поверхню стіни праворуч. - Вінстон повернув вимикача і голос дещо вщух, одначе слова що лунали ще можна було - розібрати. Цей прилад (який звався телезахист) можна було приглушити, але не було - жодного способу вимкнути його повністю. Він підійшов до вікна : маленька, квола - фігурка, його худорлявого тіла лише підкреслювалась блакитним спецодягом, - що був уніформою його партії. Його волосся було яскраво світлим, його обличчя бул - природньо рум'яним та життєрадісним, його шкіра була огрубілою від господарчого - мила та тупого леза бритви, та вкрите крижаною маскою зими яка щойно скінчилася. \ No newline at end of file diff --git a/src/test/resources/test.txt b/src/test/resources/test.txt index 06bd427..849f527 100644 --- a/src/test/resources/test.txt +++ b/src/test/resources/test.txt @@ -1,5 +1,31 @@ -To be, or not to be: that is the question: -Whether ’tis nobler in the mind to suffer -The slings and arrows of outrageous fortune, -Or to take arms against a sea of troubles, -And by opposing end them? To die: to sleep; \ No newline at end of file +Стояла ясна та прохолодна квітнева днина, на годинниках пробило тринадцяту годину. + Вінстон Сміт, притискуючи підборіддя до грудей щоб сховатися від підступного вітру, + швидко ковзнув крізь скляні двері великого панельного будинку що звався "Перемога", + але не достатньо швидко щоб завадити вихру з піску та пилюки увійти разом з ним. + + У вестибюлі тхнуло вареною капустою та старими драними килимками. В одному з його + кінців був кольоровий плакат, завеликий щоб розташувати його всередині квартири, + прибитий кнопками до стіни. На ньому було зображено лише величезне обличчя, + більш ніж метр завширшки : обличчя чоловіка приблизно сорока п'яти років, + з масивними чорними вусами та привабливо суворими та прямими рисами обличчя. + Вінстон пішов сходами. Не було сенсу намагатися піднятися ліфтом. Навіть у + найкращі часи він працював лише зрідка, а відтепер черговий електрик вимикав + його взагалі під час світлого часу доби. Це була частина політики заощадження + під час приготування до Тижня Ненависті. Квартира знаходилася на сьомому поверсі, + і Вінстон, який мав тридцять дев'ять років та варикозну виразку на правій + щиколотці, йшов дуже повільно, відпочиваючи по декілька разів під час сходження. + На кожному поверсі, навпроти ліфтової шахти, зі стіни пильно дивився плакат з + величезним обличчям. Це було одне з тих зображень,які створені так щоб очі + невідривно слідкували за тобою куди б ти не пішов. СТАРШИЙ БРАТ НАГЛЯДАЄ ЗА ТОБОЮ, + промовляв напис під зображенням. + + Всередині квартири солодкий та принадний голос диктував перелік цифр, що якось + стосувалися виробництва чушкового чавуну. Цей голос лунав з видовженої металевої + тарелі, що нагадувала поблякле дзеркало, та була вмонтована в поверхню стіни праворуч. + Вінстон повернув вимикача і голос дещо вщух, одначе слова що лунали ще можна було + розібрати. Цей прилад (який звався телезахист) можна було приглушити, але не було + жодного способу вимкнути його повністю. Він підійшов до вікна : маленька, квола + фігурка, його худорлявого тіла лише підкреслювалась блакитним спецодягом, + що був уніформою його партії. Його волосся було яскраво світлим, його обличчя бул + природньо рум'яним та життєрадісним, його шкіра була огрубілою від господарчого + мила та тупого леза бритви, та вкрите крижаною маскою зими яка щойно скінчилася. \ No newline at end of file From 80915be35aece26e4ffa7a7b4c571660026740c2 Mon Sep 17 00:00:00 2001 From: Denys Date: Fri, 6 Sep 2024 04:47:00 +0300 Subject: [PATCH 16/21] Upgrd UKR lang --- META-INF/MANIFEST.MF | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 META-INF/MANIFEST.MF diff --git a/META-INF/MANIFEST.MF b/META-INF/MANIFEST.MF new file mode 100644 index 0000000..e523bee --- /dev/null +++ b/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: ua.com.javarush.gnew.Main + From 7aef6b3f8d9e277a1425e78d780de5f73f35df19 Mon Sep 17 00:00:00 2001 From: Denys Date: Sat, 21 Sep 2024 16:05:19 +0300 Subject: [PATCH 17/21] simplified my code --- out/artifacts/GNEW_M1_FP_jar/GNEW-M1-FP.jar | Bin 0 -> 13620 bytes .../gnew/crypt/code/Cryptanalyzer.java | 51 +----------------- .../test [ENCRYPTED] [DECRYPTED].txt | 31 +++++++++++ src/test/resources/test [ENCRYPTED].txt | 31 +++++++++++ 4 files changed, 64 insertions(+), 49 deletions(-) create mode 100644 out/artifacts/GNEW_M1_FP_jar/GNEW-M1-FP.jar create mode 100644 src/test/resources/test [ENCRYPTED] [DECRYPTED].txt create mode 100644 src/test/resources/test [ENCRYPTED].txt diff --git a/out/artifacts/GNEW_M1_FP_jar/GNEW-M1-FP.jar b/out/artifacts/GNEW_M1_FP_jar/GNEW-M1-FP.jar new file mode 100644 index 0000000000000000000000000000000000000000..028287bb45d4c1c6f8c583b1354405d24603d3db GIT binary patch literal 13620 zcma)C1yo&0lLitTg1ZNI4^D6i?oRUZu!jbB3-0bN!6mo^cXtWF-Cct&%*;+Q|4#C6 z0q68RbX8a1u3KI5$xA(Zjt&L`0|S=xl0pOQCqf5%4kjb2EJ!aYE5;}zC@U!@s-(;y zBX-{h26iel&@U}T&oGK8MNcy{FkGR?G{L&Gej+n4Fm5{}NykvFNF_5NH8ecg|AtPA zj)s0{L~2-ye)<{p()!9e1em-OG)&mQE{(wBdQX4yk6OTifx&?NA1z=X|NFNVzn=E& zahffF@z)ce|C|7{F#F9U}N&LyAL}!V)uJ`=NcBnawPYWSE_k~#syY# zAZb>@*{D4s#VsdA1S14vmHOhqVqFkk1YJZwBl0*LQK|W?-}DjTnbp|U<{&eXlL zsRG0A`RIlR^-lh9b3Iq{{cCgD@5Ej{V^~Aq_f;ngwuANJ)ki)qdz*W=s^_no72`aA z@4JXlxPHeQ+*%8X_DZ@9-Ai${m@P3kM$cx#oIov9=rAH4rTRTbuofel*X_ns3S-Lk z-5>#!@DQXyLGL%#R|6FAxmlOhH5~Sl3sSEJavPoP?bmQ64?iLXc)JH(rhx|xQsC`Hu=Fs zz=fpd8_a}7_UBnsam2&ww4zB9sA97ImSm4z)Ym-dDn?LHY9fX3Z!-CuOZePN8n51b zkP>p!Z`<5C}uI zH7KV~bt3PpyAYib=1%`?bFoK&H!>rwMh|6d?X}B*5F9ww=nIt{wY< z0ah;K5EkJMA}eKLH_%B~VH*9MUbHbk&%$JfC-GWX<}M=VUR`N%aw0V6UPQ?Pv{Rq6 zFg1~8yh9+W!vF4A_N1T{{@SD!roEkV$=@ZKry%jb>xA zwh>+9NJ)?hLdT+pg7!Q2fNPF54YAw9CggLuEx?0EN*y>~0wR?`bp}>57HL8)K@|M) zj{B3V^!z+2*74}#P9MG4uU#D8ulxhh%JGBEZ@d!m?-_v>diuX{ORWD7Zs8{l0OkNw zM<;!&KYi1_>RVGK75w|5Z|5cZ`(0_aSwMg3`${}5f_4%D1Tl{E5i@UZzysxVyPwwYbIeE4O@VDb7SC^kk3v21%bdX|+1qS|-V72J3Kv z!_~fn`N4-Yi(k35uqC$*NhSR{-?`a92Ik88y4GOZHIA)rf0Q0ehr`8SdSWurJlOA zrTium&v)erHgQPc6TN(s@ZN1w+AH5pV`o`T>PmX@28gpW1${3=@rh{OUyu09z@;jc z;S941)OAX?0XOK)RnqOKn+W(6yv-GlKO)kP6G(o#_Fdb0g)y7ragm1v5J6`vG-@5v zXUDFVCgm6cR-GKf4pv@LhOt|{DoK|~cl)%Pp+TB7sxhfr>tfW+07*b&xB96Q^=lJq z5agK5OFSRF`%Lq$s*em2s}ZbL^Mn|Tz)}w@!TzBguT98TA80h7+W2=EFm67l9f&bx zy^TC*{a{5NQ~wfn+gYGf@GM+*wVwPAHDWTA<)JoE_v|>iDglQt4#kKbI>Dt2_A9bD zS%-pW*Lq#4jcGSCM)x|-F`F3nAU`7PNa=epF9;P?w=(pqc{T3w(9oR|Y||yY9V?v(jLhTgH|kR_%Z|QfEu@#PxwY9e zz?5?^tV_~+J5y}mKZvBI=~VDGsVt6`n8O9 z-j)OXZkDT(!gbp;&A(t1k+e+>qvka%JageI&=|(uYtgiMNATjvbyt|)BAz>0 zfNzNSc~IEU>{oxG80=xvH*|83P;-}w+nhoi3QCh9qk6gQl51=vEZc54C2Acls>56*febRVOKg8em&N9~Vb&H8Z3J-blo9L)1t_Bj2gjCjB$SHsRV9Q|! zw!lV-aVyq#3Oys06^}eG+5UEu@sLw&zc$WhAOsXp7PUO#UNo2*8ratwZ^e}3AMxoy z@G1>iLM2=g850gd>OKdfvV48&2)f?K{}$@g3iG!hsMpP?a>Sc3x%p(t6Ay{s!`N7d z-5os$t@e>IP;%j%dT-l}+EF?_M4wB4w#S#e4-HRpWI1|y*we2(!c#P=lGz|G=H9Y< z0G!%qWjQD0I>T^uN<+Af#dj4@y%*5sC!=(yh$1AFsn+*yC@^6r!F}hyACGPpkGkIz z3FIn6avTi;w?xRviYpvovDjTAoYAOcVBGQf>y_A?MZV39i_UubRhDFQ6K6aR)%}Lw z*n!_jM$i~sG#0ctD%F@3_ez|xY|?4;K1J7HZ*yy~`Hx^;Hn5(s4-yPa8sX0y>fcj} z|IbySXlpKHWox5vU||K+|MRL?S2r#r+VM%EBXhXYECdJdPDfrJ$r<6I#!Y zz8e@?!i5~KDq$RiV=JO@LLljOGmOTH&eQRAA#3um!{9tExoogSS?aZFP>rIm(e%pE zAYJYO6uTkn!QaI~9Ezo_S!gik3Nqo8wz%VP+pQ@PlvqJ^F16&eC0#p+Ec+muoc`ou zk*QLR@sZ4>SDwdNmW5KHKoq{^Rs>GIye?_T3gv;WO7;WPpXY; zz{Zx3XX9Qs&`5}c_6w zCDiHf9fi;wbW>nz$4%u|l(i++F&o<h90szm|yaWuT0h?NI?;krA^b+E7rfyRW;twP6Wh) zd@bEG4d?L9cV2jF!(-SM3n=>hb*5J8x&I({mXmmTkA%ofZ6_2<8Tlq>6Gbua^imOJvOUmrH3jMiAhsaNeMedh+?|iLFGt2 zTcYMIUdl5q1VW6Lb`pjhvT>i&*(Jzo4QV3;9GtfAvKGc$HYf&(zjv~7>S5wmny&&f zE;~V!7jaG0%*7j5Q0!Ex7qJ`n@hjr3TAmn4OHrI>e>8+Nm{ZP!OU24-D5GJd%?hSo z(|}%+BMk6~f=bh>gFm9bvK!=uKBmBW;SwZQLq6cwm7Ay_fY;^%FOqKf;)`lauO~z( zb;WhY^HY(L^&(3i6ZBFmDA7A?dx(cdj}w`>WG}|}!~RPe3xJ{+n@S*@3#7(qu*~KM z=aJQZc+6`!Xk%qVnTVR6!qgUpw;44?f-+?_SM*n5K$4K&^*OhJQtIPa&ZaQfO0BW5 zM0*7Sx^qXDPj@ipygou{-CA>D(X#(mz=Ik4VM(`ykM6S&`sYgJ``#1}#knq_L@$=P5X*_9a?S3FIhqkzBB#7# zWQr9gie;+JHbePR(g{bxc3F=fEBvhDLs&uO(6W-1uJd{Mwq&jsc0=)9D#6L^(20>Zk z_jl5&Q|pRnIpAFeqyb~D5QSDQleHN#HEtnII^LG4YG;PHTN+&@Pkew z=&T)A2!+;D3fLZ4Wx_MX`{j?NkAe zxQ1L|^56FBD8%FO-_uWhb5sI27sy2KR|1eFpAW>P_4f&yx>0w&Gd;Qlhr@^ zOw6TxAzo(+&w9WKZPm9yQn3fsS9?D@^|R`i_`-J0bE|dlS!R?kWqy+iOL;B2J9X*Y z4G!U|a}BodD4P4%8i$9RiAZ}zYKB8YS@v@8aiqh+*J+KE*G@goox@F_{0fZ(EK5q! zqqUk@slo%(PEb3$>mnnaaHuN7PNmAYwi!7+PoB>& zq3G(LU7wcig16Am<^NMH#nQmAAips4=MK|qxFv9F1!^Mx0RlDkT}VLP4p6ifKv^WyYCor%{T@OH;)Z(uSPU@ihHx1)1_Y8=q(v!{#~4Udg;DxO z?T{xaGa5*;qs{a4)RQQ>KEtS!P?2csmnoQ1Kn@4Sh$)M(0PF-bqD_cKA zUg71~)ZmHB^~q^ocN$juWZiN8)T@s!Z7htwd-=dRke>tZ_^!9~)PFqDhZ31}iFZ(Y z3HgNe1@7UJUCHK>jtRdm@k3l^fkXTj&6Gq+BWVd??;MI+0*}>Ebc0H+&kh-9X(miy z%I9#Rott<#Tf(Z1O43HAILTpp*^_r%ePc;L`4CHVL8p5*r zzQ|Jx$N&8#%{6UtAbG8{d0I=vCfHn$N{|5b#vngRG0-aNpfahnzE$L28Z<^bjqyqB zwxzT=J8yMld6aG2IWXC24H_+xB{0(V@?$P_Ar*>PVs#cEIRqcNiyf!PTxR?Q84Z81 z&YY6vZsG;8ir}Gcwn43dhcko>H1Y>hJtzg9)oI$qgE$5Y)p0K>8j?#Uq^@Y;JyQOT zDgax~HcU|f7^AUOKl~`48$D-t6c~}*Rh+g-h&#xLB8oe{j6o@Q$b{@6U9nYW3O46 zl*qqMxVE38Gj{ep)-QA{)~|&5;@;byR(FK$1qE`|Ub#+ClC%b(Z`Pl_Q*AYE{` zwPWm_%#B}8!Anwt!i!iYvyRu+DlJhPqjmmYQNQv#Az;CM?(WFCIGYG`2q z@?30i-o+VCX`7@B^8==4rhX)H$i-74XXM_EE%1*QQnxG2GGD83r}Vd&Ev4pGyn1*$ z#N;pDH_6jH7L4{Pv)q1c6U3*bBJPMv@Z1QZ`S$twDHdE|T0VK^6(iU+K?ARiKAGHcC~oS=P@VY>5x^@!UkgiR@q?*VIf`m+uFEw|HxQyzk0#LE1| z_d80`cQ2IE06UlQ-%xg}h3-7%v3#x@7ecS$`8Yw7slI4@aIpLyVL}7nB%=gS)K3QX_7YeP4KKTg zOBca;Tj#;Z9r*i5X!1~FkvgGK5WNpXiw`oS=`ya>LHcQ^4Nh5T?_Qkpe?(^Y_MXHq zQNbn1^9)X{z(Iu|?R1;P{p9TJ#Fq-$h+4g9+7TrNS-uU7_{m+p~lM*qbA?ZM>O|hubC4s>9lOuiov!S96&`T%+K(tm^r2ecLZ?W^Sdl^Sv%U}%C zX1OdrV4t_w1$>yFg5~wZNcZ3|JM)(4uBo4VZ?}Zet%*k#ys-_8Tcj~As8chlr`cgrrtJ_Oh}s5n zwQUKCy0`vnp_S# z=u#FGi64`VJ@4MjHfjhA=b4ZiW6gJAX5}W$^*UC&gFjhWTooPSBsdtD`=g~jS=pbZ z12KeuHotz^IgTMu)MniA)G+SN8-m#gIYNOv3Ticy1Tz6yu?*<>?3$*EjAZ&9F<%w=&%fY#^goBOg^gLn}78SoM=+N!YpERX1Ecr^M;I zPZk+RqW99qkylIK_^a(>8IoILD1{lG90O&*qF~_vo;xW`AEB)^NcFHm+xtnDD`fA4fFQZLY(uR zg}k=wqDaTePP3IFAJ;(UjGiMbm5mQrm7V*PG2Jp>E56k7!r^&kM8Muze!fPcy*TlX z7&PKs5WnXu<9xc;`q!eKgatV2ePweav^%_6w-Ib3Vc?zya)}+%6j?Ag9J3mp1k6nS zS;4PAri9Z%%=e1*F?YwEaZ4Vy-{CF*m%w?cJ{zL>2n<-=a*dbt5&L#43-FsRH9B}- z#L6POS2mSj8pw3LtTYkE#X$_il_u8AvOZ0jl3@eHW@o-OSbD}OtK-5E{clpQwsOXiqC$oz@v2Om5+D@8tBv66do@L$|s*9QAbEzIfZ_)0W z%mZ~l<4JLw={b&@D+=b)Bef zu_Ft0Tw|xh4p&FV_Luen(3Y;nFT80l{Al!bFN6x~jl-zNC$gGSv@~Ak;=tKRa6IzB zgtvu`6Rd4cD3PQlN+L|#A5?H--aEvK89X{2V0u8qY3=+ncOQAn378>7>Ie-+$vkP!KHPsadlOXos6H+|Lms==2L`|71`gJ*q2 zgcwa>%6=XH@aXyS`Stup5=IYq1u#YtWw%@D;^E8HYL2p<>(g-HYzCCVl|JMR=_Ps z%=^q)ur^X7T(Vn18NY71jWzG{2B8^fkKUNO>*}s|HK6d&K-B)}s8&~KI)uN_$n(Dx5W4=>dl!61oZTs8Q10BscNa8y+LjX_X?VrK&m4VwG7v{(g&BYITTHR zn-H0NWtyoD9^}fDL0O4wu+Z{)2V2g}>v;Jg%+i1-IEK4RoS_ZW!Wn7Qh;YgR$DSM_ zV05)-6U)mtO~MzJz&ncCt6Q{>lT<`q!Q{lPi$CI7pO2CD)NFL>ch*;W-c)kPP%$aku!k29w+YWfSV51+PCOO$fHEauPDWckf2*nl> zyqY}Ka73bdmXch?{kc3Wj_JkL2wyh!3DmdD*BlcJJufY_)Ye#aFbP@RXAiYE{{TbI zyp(P*P6B<-Lue)6PkL3dl3qemDjOoa@M;II{qo2)liB9@8J*%`Jk_$_6^hw65;C{o zG$xdbAl8Y!+{%Ob_n5ESMSY!{dzKMzledrHt_vxbmksBC7KbZ7NK|bwfz!9pQ|2Y-C_hh{Be&y%<#eAK!JhL zBKQsDrk$tE*A@$%{Jx5a&;bhE( z{G5jGrAnh}vD03$AE8r$xBNDTiI#Uq!24bv){;P&`)zuY_;5Zu@En2>?iPvu^Fcyn}|sN=rdY`hvcP znRL?9;gjE*Q5JCa4h)4vD||G70d^kl0`OY6ze3#?(QmV^6PYSMb`Vr2`?+06Tv?Fu zMfe@03gc-Rm+!^a2MdFc`e<){-ysYeolQrT*JkVeqUM}l9OVsbMmZ=gg5?~UGp}$0 zYBfo%b1Vr)3Q)l=!diY%#V7dnHEF-S7KSuX_ zG36;(|BA(K$nOzViHDM0O67o&n{PFt7!YLIxvQZoT=4A;ECvYDkV(RW+n_jIGs{F& zQR@TdCK&>)1L7u*5QA4nLI9V{W`N~nLhh3EM^2S)pZ;B^^JFNRRFu9^O&3UU|8GXp zt(>})XMx6^xiX}M+z=>G461!AJF*cs}3eP~8!*w~e5mlH{vfepd zx(S$r_()3->$d*4{?R?-G4D|sBIiS#fSIPjb?3nT_^#l*NGSy1s0_Puid8YR&S9lD z2X#(}^3=`@A=aR<&YFyp5yBwO;8NE53SCXkghmQgMsR}4IcRdMqyEhq_bIL*{^H2K z$}2?#{u&h=S+U*N)(sC*zQLF3C?-`dIBmPCuLxKRVz4ZW$|M@IM&09ANH7BpwFqjq z270Ds1(0kxEGK)P*~$!3?j$;C0E`lCCQJb$^mW8crIJgb$J)nCUs!Fzs zPTB;%Y#w#{%LkB7m6^HJRlIqcOdZWKMf*XB#&&HH6OfT%{1crU;=2{ioI|b3HzPep zX9Vg{H?8w-Nlk8XTirZoDl`bS5HVuD8hW&Ch*2Vl$lJttfGoQ0bNutF@9&YCyWW<) zdh0$$bm5o%#po9Ggn%uKZW-%k7Jdkz+SX~4omLc6N3Hn$z%K?~MppJIci$C#iX$Afb%jZP zEN)~4NufR6P_?cs>gJTgNO-}p8gd9L8Wwco_f>ci46p#hIPY zp_})IWL;)Z<(Tb+FLfo_1p(7mqvbQ64`@8cTz1Q^w(GrM2uFcSYBtOEHmh=HOGIPe z8Rx(AcW98#Z_kblSC6011(2HCQTE)MkwrYCydk)HX5FK-p?@3VXcP_TvtYk`Z-)Wd z=k{#ZOO}wmrT;~`#DW8H8DTt?0@<|xId)=NBx zk?KkL#ujsJcvvoGy4TlTRDgzF+UJVu8t( zWsgf6PqA)VQF+Nq6+_H1tcgf$?thY6Jw1+SB2y z*d2(zdgJGONq`Y5Rqr7i`ci%KL!xhk;kE6x`2g=M4=v?Wj*LA~0vb2Hx`@U*U%*Ul zIzydm%@-#U1^8#(CdIl%#0c3B*xhDx0EuF*RJ0OS1e~}S#-MYyNbW(tSTPDjhI?5{ zX`on_5RzI z=G(hsCBeoGal!Eg8xccZw*;*65Xf))Ogc^V%r9kehzB})AUEJvF8m|18$5AVu&8k< z(O)0cc~-j zw$#V6^4nJaWCNHm7(!-t=4a?x-4B*yNAl7nDJ-x(l2&bk5}4NYwFM4jXa)En&U2ii zjI;C!Tw^57;)uObIL6_)E>gO#6=S;82a#{LI_v0{vgtkVv|~IeyaKWj&RC^WiJfoz zSsBl1$}2Y^RN_e z>;E<4QCT!WbiSH-JCKHEeWi-BGTWOkfv4bkj4~4bA?(K2{Pe&twJGHN3?0p59lqYs z{4HTG=VmYyClHtQ4^pD659+KBZ@<*nK0g9y?C&A5Xt$CVi1_SACie*@n=oKuNdgfl zblg~acSTCFXnZN9F4!wJ(@KNiwkr|{;6xF_Ag2T}kL^f{1WeJOzD1ko3B8j~LpC*# z$>t|(*jf0rJz(VAmAjH2XnS#&?}qZKK4|KNO_3PQ8;ue##0gm1*S7+$5y$cJX$nZ@{e-*)e6 zq9WZYrs<@b!^9}_wQU^X_*=OHtI{pPFl$GZ{;_I~1CM@VE!2~3Wc%H~v^`dhGXJO= zfkU8!{eYbOj4XdbvHz3)Mw9;srd?hN90CsP*C_NKQhXnWe@pot+oNtjQSsyW4~+V+ z*Lgyz|Dd7A;UmMJnDt*XJ)zcr(COpwFQ%U`?7!xILb3lKlE+v2pWJ_8+J7zLsW$h6 zlz%1SZ*cl!lJVofo>1;T<6ECl?msBvzYF_Y?4O_a@6O{1A^U^M9xum#-RuA2Wq-Y6 z;vZ5TM?1e4^cQ~ipIiPJF!cnB`ax8WIoxm5`a{~k;Aww;r%$Qd&mF*jE}-;?(fV%- z{0j=}cQ2Oshx(7B)kmB9*9Crb1OH(HPo06Edks&G#UDh1`QN4e5d7bb;Hh8ngQy-K z|5ew&x)(oA?Mcg@Yt>Kviy!pvw{reZH{<8idb-elPTv3dIfXuE?Ek9ZkHYuwPUb1! z|3OovzYz9!_WxtQPe$}}4EdD*{~%3;wTz%|GK literal 0 HcmV?d00001 diff --git a/src/main/java/ua/com/javarush/gnew/crypt/code/Cryptanalyzer.java b/src/main/java/ua/com/javarush/gnew/crypt/code/Cryptanalyzer.java index 4afbf87..854a01f 100644 --- a/src/main/java/ua/com/javarush/gnew/crypt/code/Cryptanalyzer.java +++ b/src/main/java/ua/com/javarush/gnew/crypt/code/Cryptanalyzer.java @@ -62,55 +62,8 @@ else if (Character.isUpperCase(symbol)) { } public String decryption(String str, int key) { - ArrayList ENG_LOWER_MOD = new ArrayList<>(ENG_LOWER); - ArrayList UKR_LOWER_MOD = new ArrayList<>(UKR_LOWER); - Collections.rotate(ENG_LOWER_MOD, key); - Collections.rotate(UKR_LOWER_MOD, key); - - ArrayList ENG_UPPER_MOD = new ArrayList<>(ENG_UPPER); - ArrayList UKR_UPPER_MOD = new ArrayList<>(UKR_UPPER); - Collections.rotate(ENG_UPPER_MOD, key); - Collections.rotate(UKR_UPPER_MOD, key); - - char[] array = str.toCharArray(); - StringBuilder builder = new StringBuilder(); - - for (char symbol : array) { - if (Character.isLowerCase(symbol)) { - int originalIndex = ENG_LOWER.indexOf(symbol); - if (originalIndex != -1) { - Character decrypted = ENG_LOWER_MOD.get(originalIndex); - builder.append(decrypted); - continue; - } - - originalIndex = UKR_LOWER.indexOf(symbol); - if (originalIndex != -1) { - Character decrypted = UKR_LOWER_MOD.get(originalIndex); - builder.append(decrypted); - } else { - builder.append(symbol); - } - } - else if (Character.isUpperCase(symbol)) { - int originalIndex = ENG_UPPER.indexOf(symbol); - if (originalIndex != -1) { - Character decrypted = ENG_UPPER_MOD.get(originalIndex); - builder.append(decrypted); - continue; - } - - originalIndex = UKR_UPPER.indexOf(symbol); - if (originalIndex != -1) { - Character decrypted = UKR_UPPER_MOD.get(originalIndex); - builder.append(decrypted); - } else { - builder.append(symbol); - } - } else { - builder.append(symbol); - } - } + StringBuilder builder; + builder = new StringBuilder(encryption(str, -key)); return builder.toString(); } } diff --git a/src/test/resources/test [ENCRYPTED] [DECRYPTED].txt b/src/test/resources/test [ENCRYPTED] [DECRYPTED].txt new file mode 100644 index 0000000..849f527 --- /dev/null +++ b/src/test/resources/test [ENCRYPTED] [DECRYPTED].txt @@ -0,0 +1,31 @@ +Стояла ясна та прохолодна квітнева днина, на годинниках пробило тринадцяту годину. + Вінстон Сміт, притискуючи підборіддя до грудей щоб сховатися від підступного вітру, + швидко ковзнув крізь скляні двері великого панельного будинку що звався "Перемога", + але не достатньо швидко щоб завадити вихру з піску та пилюки увійти разом з ним. + + У вестибюлі тхнуло вареною капустою та старими драними килимками. В одному з його + кінців був кольоровий плакат, завеликий щоб розташувати його всередині квартири, + прибитий кнопками до стіни. На ньому було зображено лише величезне обличчя, + більш ніж метр завширшки : обличчя чоловіка приблизно сорока п'яти років, + з масивними чорними вусами та привабливо суворими та прямими рисами обличчя. + Вінстон пішов сходами. Не було сенсу намагатися піднятися ліфтом. Навіть у + найкращі часи він працював лише зрідка, а відтепер черговий електрик вимикав + його взагалі під час світлого часу доби. Це була частина політики заощадження + під час приготування до Тижня Ненависті. Квартира знаходилася на сьомому поверсі, + і Вінстон, який мав тридцять дев'ять років та варикозну виразку на правій + щиколотці, йшов дуже повільно, відпочиваючи по декілька разів під час сходження. + На кожному поверсі, навпроти ліфтової шахти, зі стіни пильно дивився плакат з + величезним обличчям. Це було одне з тих зображень,які створені так щоб очі + невідривно слідкували за тобою куди б ти не пішов. СТАРШИЙ БРАТ НАГЛЯДАЄ ЗА ТОБОЮ, + промовляв напис під зображенням. + + Всередині квартири солодкий та принадний голос диктував перелік цифр, що якось + стосувалися виробництва чушкового чавуну. Цей голос лунав з видовженої металевої + тарелі, що нагадувала поблякле дзеркало, та була вмонтована в поверхню стіни праворуч. + Вінстон повернув вимикача і голос дещо вщух, одначе слова що лунали ще можна було + розібрати. Цей прилад (який звався телезахист) можна було приглушити, але не було + жодного способу вимкнути його повністю. Він підійшов до вікна : маленька, квола + фігурка, його худорлявого тіла лише підкреслювалась блакитним спецодягом, + що був уніформою його партії. Його волосся було яскраво світлим, його обличчя бул + природньо рум'яним та життєрадісним, його шкіра була огрубілою від господарчого + мила та тупого леза бритви, та вкрите крижаною маскою зими яка щойно скінчилася. \ No newline at end of file diff --git a/src/test/resources/test [ENCRYPTED].txt b/src/test/resources/test [ENCRYPTED].txt new file mode 100644 index 0000000..9523a57 --- /dev/null +++ b/src/test/resources/test [ENCRYPTED].txt @@ -0,0 +1,31 @@ +Тупамб атоб уб рспцпмпеоб лгїуоєгб еоіоб, об ґпеіооілбц рспвімп усіобечауф ґпеіоф. + Гїотупо Тнїу, рсіуітлфяші рїевпсїееа еп ґсфеєк ьпв тцпгбуіта гїе рїетуфропґп гїусф, + щгіелп лпгиофг лсїию тлмаої егєсї гємілпґп рбоємюопґп вфеіолф ьп игбгта "Рєсєнпґб", + бмє оє ептубуоюп щгіелп ьпв ибгбеіуі гіцсф и рїтлф уб рімялі фгїкуі сбипн и оін. + + Ф гєтуівямї уцофмп гбсєопя лбрфтупя уб тубсіні есбоіні лімінлбні. Г пеопнф и кпґп + лїочїг вфг лпмюпспгік рмблбу, ибгємілік ьпв спиубщфгбуі кпґп гтєсєеіої лгбсуісі, + рсівіуік лопрлбні еп туїоі. Об оюпнф вфмп ипвсбзєоп міщє гємішєиоє пвмішша, + вїмющ оїз нєус ибгщісщлі : пвмішша шпмпгїлб рсівміиоп тпсплб р'ауі сплїг, + и нбтігоіні шпсоіні гфтбні уб рсігбвмігп тфгпсіні уб рсаніні сітбні пвмішша. + Гїотупо рїщпг тцпебні. Оє вфмп тєотф обнбґбуіта рїеоауіта мїхупн. Обгїую ф + обклсбьї шбті гїо рсбчягбг міщє исїелб, б гїеуєрєс шєсґпгік ємєлусіл гінілбг + кпґп гибґбмї рїе шбт тгїумпґп шбтф епві. Чє вфмб шбтуіоб рпмїуілі ибпьбезєооа + рїе шбт рсіґпуфгбооа еп Уізоа Оєобгітуї. Лгбсуісб иобцпеімбта об тюпнпнф рпгєстї, + ї Гїотупо, алік нбг усіечаую еєг'аую сплїг уб гбсілпиоф гісбилф об рсбгїк + ьілпмпучї, кщпг ефзє рпгїмюоп, гїерпшігбяші рп еєлїмюлб сбиїг рїе шбт тцпезєооа. + Об лпзопнф рпгєстї, обгрспуі мїхупгпй щбцуі, иї туїоі рімюоп еігігта рмблбу и + гємішєиоін пвмішшан. Чє вфмп пеоє и уіц ипвсбзєою,алї тугпсєої убл ьпв пшї + оєгїесігоп тмїелфгбмі иб упвпя лфеі в уі оє рїщпг. ТУБСЩІК ВСБУ ОБҐМАЕБЖ ИБ УПВПЯ, + рспнпгмаг обріт рїе ипвсбзєооан. + + Гтєсєеіої лгбсуісі тпмпелік уб рсіобеоік ґпмпт еілуфгбг рєсємїл чіхс, ьп алптю + туптфгбміта гіспвоічугб шфщлпгпґп шбгфоф. Чєк ґпмпт мфобг и гіепгзєопй нєубмєгпй + убсємї, ьп обґбефгбмб рпвмалмє еиєслбмп, уб вфмб гнпоупгбоб г рпгєсцоя туїоі рсбгпсфш. + Гїотупо рпгєсофг гінілбшб ї ґпмпт еєьп гьфц, пеобшє тмпгб ьп мфобмі ьє нпзоб вфмп + спиївсбуі. Чєк рсімбе (алік игбгта уємєибціту) нпзоб вфмп рсіґмфщіуі, бмє оє вфмп + зпеопґп трптпвф гінлофуі кпґп рпгоїтуя. Гїо рїеїкщпг еп гїлоб : нбмєоюлб, лгпмб + хїґфслб, кпґп цфепсмагпґп уїмб міщє рїелсєтмягбмбтю вмбліуоін трєчпеаґпн, + ьп вфг фоїхпснпя кпґп рбсуїй. Кпґп гпмптта вфмп атлсбгп тгїумін, кпґп пвмішша вфм + рсіспеоюп сфн'аоін уб зіуужсбеїтоін, кпґп щлїсб вфмб пґсфвїмпя гїе ґптрпебсшпґп + німб уб уфрпґп мєиб всіугі, уб глсіує лсізбопя нбтлпя иіні алб ьпкоп тлїошімбта. \ No newline at end of file From 30291a5d14daf7d8c97c9060ff87b981acc7c124 Mon Sep 17 00:00:00 2001 From: Denys Date: Sat, 21 Sep 2024 17:54:01 +0300 Subject: [PATCH 18/21] compressed the code --- src/main/java/ua/com/javarush/gnew/Main.java | 2 +- .../gnew/crypt/code/Cryptanalyzer.java | 4 + .../gnew/crypt/code/RunBruteforce.java | 190 ++++-------------- .../test [ENCRYPTED] [DECRYPTED].txt | 31 --- src/test/resources/test [ENCRYPTED].txt | 31 --- src/test/resources/test.txt | 69 ++++--- 6 files changed, 81 insertions(+), 246 deletions(-) delete mode 100644 src/test/resources/test [ENCRYPTED] [DECRYPTED].txt delete mode 100644 src/test/resources/test [ENCRYPTED].txt diff --git a/src/main/java/ua/com/javarush/gnew/Main.java b/src/main/java/ua/com/javarush/gnew/Main.java index 0a13809..2ebee7d 100644 --- a/src/main/java/ua/com/javarush/gnew/Main.java +++ b/src/main/java/ua/com/javarush/gnew/Main.java @@ -43,7 +43,7 @@ public static void main(String[] args) { String encryptedContent = runBruteforce.bruteforce(content,dictionary, dictionaryUKR); String fileName = runOptions.getFilePath().getFileName().toString(); String key = runBruteforce.getKey(content, dictionary, dictionaryUKR).replace("Key: ", ""); - String newFileName = fileName.substring(0, fileName.length() - 4) + " [DECRYPTED Key -" + key+ "].txt"; + String newFileName = fileName.substring(0, fileName.length() - 4) + " [DECRYPTED Key -" + key + "].txt"; Path newFilePath = runOptions.getFilePath().resolveSibling(newFileName); fileManager.write(newFilePath, encryptedContent); diff --git a/src/main/java/ua/com/javarush/gnew/crypt/code/Cryptanalyzer.java b/src/main/java/ua/com/javarush/gnew/crypt/code/Cryptanalyzer.java index 854a01f..c9d417f 100644 --- a/src/main/java/ua/com/javarush/gnew/crypt/code/Cryptanalyzer.java +++ b/src/main/java/ua/com/javarush/gnew/crypt/code/Cryptanalyzer.java @@ -66,4 +66,8 @@ public String decryption(String str, int key) { builder = new StringBuilder(encryption(str, -key)); return builder.toString(); } + + public String getDecryption(String str, int key){ + return decryption(str,key); + } } diff --git a/src/main/java/ua/com/javarush/gnew/crypt/code/RunBruteforce.java b/src/main/java/ua/com/javarush/gnew/crypt/code/RunBruteforce.java index 8c93141..2de17fd 100644 --- a/src/main/java/ua/com/javarush/gnew/crypt/code/RunBruteforce.java +++ b/src/main/java/ua/com/javarush/gnew/crypt/code/RunBruteforce.java @@ -1,195 +1,81 @@ package ua.com.javarush.gnew.crypt.code; -import java.util.ArrayList; -import java.util.Collections; import static ua.com.javarush.gnew.Constants.Constants.*; + public class RunBruteforce { + public String bruteforce(String str, String[] dictionary, String[] dictionaryUKR) { - char[] array = str.toCharArray(); String bestMatch = null; int maxMatches = 0; + StringBuilder builder; + Cryptanalyzer crypt = new Cryptanalyzer(); - for (int key = 0; key < ENG_LOWER.size(); key++) { - - ArrayList ENG_LOWER_MOD = new ArrayList<>(ENG_LOWER); - Collections.rotate(ENG_LOWER_MOD, key); - ArrayList ENG_UPPER_MOD = new ArrayList<>(ENG_UPPER); - Collections.rotate(ENG_UPPER_MOD, key); - - StringBuilder builder = new StringBuilder(); - - for (char symbol : array) { - if (Character.isLowerCase(symbol)) { - int originalIndex = ENG_LOWER.indexOf(symbol); - if (originalIndex != -1) { - Character decrypted = ENG_LOWER_MOD.get(originalIndex); - builder.append(decrypted); - } else { - builder.append(symbol); - } - } else if (Character.isUpperCase(symbol)) { - int originalIndex = ENG_UPPER.indexOf(symbol); - if (originalIndex != -1) { - Character decrypted = ENG_UPPER_MOD.get(originalIndex); - builder.append(decrypted); - } else { - builder.append(symbol); - } - } else { - builder.append(symbol); - } - } - - String DecryptedText = builder.toString(); - int matches = countMatches(DecryptedText, dictionary); + for (int key = 0; key <= ENG_LOWER.size(); key++) { + builder = new StringBuilder(crypt.getDecryption(str, key)); + String decryptedText = builder.toString(); + int matches = countMatches(decryptedText, dictionary); if (matches > maxMatches) { maxMatches = matches; - bestMatch = DecryptedText; + bestMatch = decryptedText; } } - for (int key = 0; key < UKR_LOWER.size(); key++) { - - ArrayList UKR_LOWER_MOD = new ArrayList<>(UKR_LOWER); - Collections.rotate(UKR_LOWER_MOD, key); - - ArrayList UKR_UPPER_MOD = new ArrayList<>(UKR_UPPER); - Collections.rotate(UKR_UPPER_MOD, key); - - StringBuilder builder = new StringBuilder(); - - for (char symbol : array) { - if (Character.isLowerCase(symbol)) { - int originalIndex = UKR_LOWER.indexOf(symbol); - if (originalIndex != -1) { - Character decrypted = UKR_LOWER_MOD.get(originalIndex); - builder.append(decrypted); - } else { - builder.append(symbol); - } - } else if (Character.isUpperCase(symbol)) { - int originalIndex = UKR_UPPER.indexOf(symbol); - if (originalIndex != -1) { - Character decrypted = UKR_UPPER_MOD.get(originalIndex); - builder.append(decrypted); - } else { - builder.append(symbol); - } - } else { - builder.append(symbol); - } - } - - String DecryptedText = builder.toString(); - int matches = countMatches(DecryptedText, dictionaryUKR); + for (int key = 0; key <= UKR_LOWER.size(); key++) { + builder = new StringBuilder(crypt.getDecryption(str, key)); + String decryptedText = builder.toString(); + int matches = countMatches(decryptedText, dictionaryUKR); if (matches > maxMatches) { maxMatches = matches; - bestMatch = DecryptedText; + bestMatch = decryptedText; } } return bestMatch != null ? bestMatch : "Брутфорс не дал результатов."; } + private int countMatches(String text, String[] dictionary) { + int matches = 0; + for (String word : dictionary) { + if (text.contains(word)) { + matches++; + } + } + return matches; + } + public String getKey(String str, String[] dictionary, String[] dictionaryUKR) { - char[] array = str.toCharArray(); int maxMatches = 0; - String KeyResult = null; + String keyResult = null; + StringBuilder builder; + Cryptanalyzer crypt = new Cryptanalyzer(); for (int key = 0; key < ENG_LOWER.size(); key++) { - ArrayList ENG_LOWER_MOD = new ArrayList<>(ENG_LOWER); - Collections.rotate(ENG_LOWER_MOD, key); - - ArrayList ENG_UPPER_MOD = new ArrayList<>(ENG_UPPER); - Collections.rotate(ENG_UPPER_MOD, key); - - StringBuilder builder = new StringBuilder(); - - for (char symbol : array) { - if (Character.isLowerCase(symbol)) { - int originalIndex = ENG_LOWER.indexOf(symbol); - if (originalIndex != -1) { - Character decrypted = ENG_LOWER_MOD.get(originalIndex); - builder.append(decrypted); - } else { - builder.append(symbol); - } - } else if (Character.isUpperCase(symbol)) { - int originalIndex = ENG_UPPER.indexOf(symbol); - if (originalIndex != -1) { - Character decrypted = ENG_UPPER_MOD.get(originalIndex); - builder.append(decrypted); - } else { - builder.append(symbol); - } - } else { - builder.append(symbol); - } - } - - String DecryptedText = builder.toString(); - int matches = countMatches(DecryptedText, dictionary); + builder = new StringBuilder(crypt.getDecryption(str, key)); + String decryptedText = builder.toString(); + int matches = countMatches(decryptedText, dictionary); if (matches > maxMatches) { maxMatches = matches; - KeyResult = "Key: " + key + " (ENG)"; + keyResult = "Key: " + key + " (ENG)"; } } for (int key = 0; key < UKR_LOWER.size(); key++) { - ArrayList UKR_LOWER_MOD = new ArrayList<>(UKR_LOWER); - Collections.rotate(UKR_LOWER_MOD, key); - - ArrayList UKR_UPPER_MOD = new ArrayList<>(UKR_UPPER); - Collections.rotate(UKR_UPPER_MOD, key); - - StringBuilder builder = new StringBuilder(); - - for (char symbol : array) { - if (Character.isLowerCase(symbol)) { - int originalIndex = UKR_LOWER.indexOf(symbol); - if (originalIndex != -1) { - Character decrypted = UKR_LOWER_MOD.get(originalIndex); - builder.append(decrypted); - } else { - builder.append(symbol); - } - } else if (Character.isUpperCase(symbol)) { - int originalIndex = UKR_UPPER.indexOf(symbol); - if (originalIndex != -1) { - Character decrypted = UKR_UPPER_MOD.get(originalIndex); - builder.append(decrypted); - } else { - builder.append(symbol); - } - } else { - builder.append(symbol); - } - } - - String DecryptedText = builder.toString(); - int matches = countMatches(DecryptedText, dictionaryUKR); + builder = new StringBuilder(crypt.getDecryption(str, key)); + String decryptedText = builder.toString(); + int matches = countMatches(decryptedText, dictionaryUKR); if (matches > maxMatches) { maxMatches = matches; - KeyResult = "Key: " + key + " (UKR)"; - } - } - - return KeyResult; - } - - private int countMatches(String text, String[] dictionary) { - int matches = 0; - for (String word : dictionary) { - if (text.contains(word)) { - matches++; + keyResult = "Key: " + key + " (UKR)"; } } - return matches; + return keyResult != null ? keyResult : "Ключ не найден."; } } + + diff --git a/src/test/resources/test [ENCRYPTED] [DECRYPTED].txt b/src/test/resources/test [ENCRYPTED] [DECRYPTED].txt deleted file mode 100644 index 849f527..0000000 --- a/src/test/resources/test [ENCRYPTED] [DECRYPTED].txt +++ /dev/null @@ -1,31 +0,0 @@ -Стояла ясна та прохолодна квітнева днина, на годинниках пробило тринадцяту годину. - Вінстон Сміт, притискуючи підборіддя до грудей щоб сховатися від підступного вітру, - швидко ковзнув крізь скляні двері великого панельного будинку що звався "Перемога", - але не достатньо швидко щоб завадити вихру з піску та пилюки увійти разом з ним. - - У вестибюлі тхнуло вареною капустою та старими драними килимками. В одному з його - кінців був кольоровий плакат, завеликий щоб розташувати його всередині квартири, - прибитий кнопками до стіни. На ньому було зображено лише величезне обличчя, - більш ніж метр завширшки : обличчя чоловіка приблизно сорока п'яти років, - з масивними чорними вусами та привабливо суворими та прямими рисами обличчя. - Вінстон пішов сходами. Не було сенсу намагатися піднятися ліфтом. Навіть у - найкращі часи він працював лише зрідка, а відтепер черговий електрик вимикав - його взагалі під час світлого часу доби. Це була частина політики заощадження - під час приготування до Тижня Ненависті. Квартира знаходилася на сьомому поверсі, - і Вінстон, який мав тридцять дев'ять років та варикозну виразку на правій - щиколотці, йшов дуже повільно, відпочиваючи по декілька разів під час сходження. - На кожному поверсі, навпроти ліфтової шахти, зі стіни пильно дивився плакат з - величезним обличчям. Це було одне з тих зображень,які створені так щоб очі - невідривно слідкували за тобою куди б ти не пішов. СТАРШИЙ БРАТ НАГЛЯДАЄ ЗА ТОБОЮ, - промовляв напис під зображенням. - - Всередині квартири солодкий та принадний голос диктував перелік цифр, що якось - стосувалися виробництва чушкового чавуну. Цей голос лунав з видовженої металевої - тарелі, що нагадувала поблякле дзеркало, та була вмонтована в поверхню стіни праворуч. - Вінстон повернув вимикача і голос дещо вщух, одначе слова що лунали ще можна було - розібрати. Цей прилад (який звався телезахист) можна було приглушити, але не було - жодного способу вимкнути його повністю. Він підійшов до вікна : маленька, квола - фігурка, його худорлявого тіла лише підкреслювалась блакитним спецодягом, - що був уніформою його партії. Його волосся було яскраво світлим, його обличчя бул - природньо рум'яним та життєрадісним, його шкіра була огрубілою від господарчого - мила та тупого леза бритви, та вкрите крижаною маскою зими яка щойно скінчилася. \ No newline at end of file diff --git a/src/test/resources/test [ENCRYPTED].txt b/src/test/resources/test [ENCRYPTED].txt deleted file mode 100644 index 9523a57..0000000 --- a/src/test/resources/test [ENCRYPTED].txt +++ /dev/null @@ -1,31 +0,0 @@ -Тупамб атоб уб рспцпмпеоб лгїуоєгб еоіоб, об ґпеіооілбц рспвімп усіобечауф ґпеіоф. - Гїотупо Тнїу, рсіуітлфяші рїевпсїееа еп ґсфеєк ьпв тцпгбуіта гїе рїетуфропґп гїусф, - щгіелп лпгиофг лсїию тлмаої егєсї гємілпґп рбоємюопґп вфеіолф ьп игбгта "Рєсєнпґб", - бмє оє ептубуоюп щгіелп ьпв ибгбеіуі гіцсф и рїтлф уб рімялі фгїкуі сбипн и оін. - - Ф гєтуівямї уцофмп гбсєопя лбрфтупя уб тубсіні есбоіні лімінлбні. Г пеопнф и кпґп - лїочїг вфг лпмюпспгік рмблбу, ибгємілік ьпв спиубщфгбуі кпґп гтєсєеіої лгбсуісі, - рсівіуік лопрлбні еп туїоі. Об оюпнф вфмп ипвсбзєоп міщє гємішєиоє пвмішша, - вїмющ оїз нєус ибгщісщлі : пвмішша шпмпгїлб рсівміиоп тпсплб р'ауі сплїг, - и нбтігоіні шпсоіні гфтбні уб рсігбвмігп тфгпсіні уб рсаніні сітбні пвмішша. - Гїотупо рїщпг тцпебні. Оє вфмп тєотф обнбґбуіта рїеоауіта мїхупн. Обгїую ф - обклсбьї шбті гїо рсбчягбг міщє исїелб, б гїеуєрєс шєсґпгік ємєлусіл гінілбг - кпґп гибґбмї рїе шбт тгїумпґп шбтф епві. Чє вфмб шбтуіоб рпмїуілі ибпьбезєооа - рїе шбт рсіґпуфгбооа еп Уізоа Оєобгітуї. Лгбсуісб иобцпеімбта об тюпнпнф рпгєстї, - ї Гїотупо, алік нбг усіечаую еєг'аую сплїг уб гбсілпиоф гісбилф об рсбгїк - ьілпмпучї, кщпг ефзє рпгїмюоп, гїерпшігбяші рп еєлїмюлб сбиїг рїе шбт тцпезєооа. - Об лпзопнф рпгєстї, обгрспуі мїхупгпй щбцуі, иї туїоі рімюоп еігігта рмблбу и - гємішєиоін пвмішшан. Чє вфмп пеоє и уіц ипвсбзєою,алї тугпсєої убл ьпв пшї - оєгїесігоп тмїелфгбмі иб упвпя лфеі в уі оє рїщпг. ТУБСЩІК ВСБУ ОБҐМАЕБЖ ИБ УПВПЯ, - рспнпгмаг обріт рїе ипвсбзєооан. - - Гтєсєеіої лгбсуісі тпмпелік уб рсіобеоік ґпмпт еілуфгбг рєсємїл чіхс, ьп алптю - туптфгбміта гіспвоічугб шфщлпгпґп шбгфоф. Чєк ґпмпт мфобг и гіепгзєопй нєубмєгпй - убсємї, ьп обґбефгбмб рпвмалмє еиєслбмп, уб вфмб гнпоупгбоб г рпгєсцоя туїоі рсбгпсфш. - Гїотупо рпгєсофг гінілбшб ї ґпмпт еєьп гьфц, пеобшє тмпгб ьп мфобмі ьє нпзоб вфмп - спиївсбуі. Чєк рсімбе (алік игбгта уємєибціту) нпзоб вфмп рсіґмфщіуі, бмє оє вфмп - зпеопґп трптпвф гінлофуі кпґп рпгоїтуя. Гїо рїеїкщпг еп гїлоб : нбмєоюлб, лгпмб - хїґфслб, кпґп цфепсмагпґп уїмб міщє рїелсєтмягбмбтю вмбліуоін трєчпеаґпн, - ьп вфг фоїхпснпя кпґп рбсуїй. Кпґп гпмптта вфмп атлсбгп тгїумін, кпґп пвмішша вфм - рсіспеоюп сфн'аоін уб зіуужсбеїтоін, кпґп щлїсб вфмб пґсфвїмпя гїе ґптрпебсшпґп - німб уб уфрпґп мєиб всіугі, уб глсіує лсізбопя нбтлпя иіні алб ьпкоп тлїошімбта. \ No newline at end of file diff --git a/src/test/resources/test.txt b/src/test/resources/test.txt index 849f527..366d032 100644 --- a/src/test/resources/test.txt +++ b/src/test/resources/test.txt @@ -1,31 +1,38 @@ -Стояла ясна та прохолодна квітнева днина, на годинниках пробило тринадцяту годину. - Вінстон Сміт, притискуючи підборіддя до грудей щоб сховатися від підступного вітру, - швидко ковзнув крізь скляні двері великого панельного будинку що звався "Перемога", - але не достатньо швидко щоб завадити вихру з піску та пилюки увійти разом з ним. - - У вестибюлі тхнуло вареною капустою та старими драними килимками. В одному з його - кінців був кольоровий плакат, завеликий щоб розташувати його всередині квартири, - прибитий кнопками до стіни. На ньому було зображено лише величезне обличчя, - більш ніж метр завширшки : обличчя чоловіка приблизно сорока п'яти років, - з масивними чорними вусами та привабливо суворими та прямими рисами обличчя. - Вінстон пішов сходами. Не було сенсу намагатися піднятися ліфтом. Навіть у - найкращі часи він працював лише зрідка, а відтепер черговий електрик вимикав - його взагалі під час світлого часу доби. Це була частина політики заощадження - під час приготування до Тижня Ненависті. Квартира знаходилася на сьомому поверсі, - і Вінстон, який мав тридцять дев'ять років та варикозну виразку на правій - щиколотці, йшов дуже повільно, відпочиваючи по декілька разів під час сходження. - На кожному поверсі, навпроти ліфтової шахти, зі стіни пильно дивився плакат з - величезним обличчям. Це було одне з тих зображень,які створені так щоб очі - невідривно слідкували за тобою куди б ти не пішов. СТАРШИЙ БРАТ НАГЛЯДАЄ ЗА ТОБОЮ, - промовляв напис під зображенням. - - Всередині квартири солодкий та принадний голос диктував перелік цифр, що якось - стосувалися виробництва чушкового чавуну. Цей голос лунав з видовженої металевої - тарелі, що нагадувала поблякле дзеркало, та була вмонтована в поверхню стіни праворуч. - Вінстон повернув вимикача і голос дещо вщух, одначе слова що лунали ще можна було - розібрати. Цей прилад (який звався телезахист) можна було приглушити, але не було - жодного способу вимкнути його повністю. Він підійшов до вікна : маленька, квола - фігурка, його худорлявого тіла лише підкреслювалась блакитним спецодягом, - що був уніформою його партії. Його волосся було яскраво світлим, його обличчя бул - природньо рум'яним та життєрадісним, його шкіра була огрубілою від господарчого - мила та тупого леза бритви, та вкрите крижаною маскою зими яка щойно скінчилася. \ No newline at end of file +THE TRAGEDY OF HAMLET, PRINCE OF DENMARK + + + by William Shakespeare + + + + Dramatis Personae + + Claudius, King of Denmark. + Marcellus, Officer. + Hamlet, son to the former, and nephew to the present king. + Polonius, Lord Chamberlain. + Horatio, friend to Hamlet. + Laertes, son to Polonius. + Voltemand, courtier. + Cornelius, courtier. + Rosencrantz, courtier. + Guildenstern, courtier. + Osric, courtier. + A Gentleman, courtier. + A Priest. + Marcellus, officer. + Bernardo, officer. + Francisco, a soldier + Reynaldo, servant to Polonius. + Players. + Two Clowns, gravediggers. + Fortinbras, Prince of Norway. \s + A Norwegian Captain. + English Ambassadors. + + Getrude, Queen of Denmark, mother to Hamlet. + Ophelia, daughter to Polonius. + + Ghost of Hamlet's Father. + + Lords, ladies, Officers, Soldiers, Sailors, Messengers, Attendants.""" \ No newline at end of file From 7c748ec6bc8e9c4617d786f17207be0a61d7c3b0 Mon Sep 17 00:00:00 2001 From: Denys Date: Sat, 21 Sep 2024 20:17:24 +0300 Subject: [PATCH 19/21] Improved code flexibility --- .../javarush/gnew/Constants/Constants.java | 33 ++++++++++++++++--- .../javarush/gnew/Dictionary/Dictionary.java | 23 +++++++++++-- src/main/java/ua/com/javarush/gnew/Main.java | 8 ++--- .../gnew/crypt/code/Cryptanalyzer.java | 20 ++++++----- .../gnew/crypt/code/RunBruteforce.java | 12 ++++--- 5 files changed, 72 insertions(+), 24 deletions(-) diff --git a/src/main/java/ua/com/javarush/gnew/Constants/Constants.java b/src/main/java/ua/com/javarush/gnew/Constants/Constants.java index aa7a999..0e364a9 100644 --- a/src/main/java/ua/com/javarush/gnew/Constants/Constants.java +++ b/src/main/java/ua/com/javarush/gnew/Constants/Constants.java @@ -4,14 +4,39 @@ import java.util.Arrays; public class Constants { - public static final ArrayList ENG_LOWER = new ArrayList<>(Arrays.asList( + private static ArrayList ENG_LOWER = new ArrayList<>(Arrays.asList( 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z')); - public static final ArrayList ENG_UPPER = new ArrayList<>(Arrays.asList( + private static ArrayList ENG_UPPER = new ArrayList<>(Arrays.asList( 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z')); - public static final ArrayList UKR_LOWER = new ArrayList<>(Arrays.asList( + private static ArrayList UKR_LOWER = new ArrayList<>(Arrays.asList( 'а', 'б', 'в', 'г', 'ґ', 'д', 'е', 'є', 'ж', 'з', 'и', 'і', 'ї', 'й', 'к', 'л', 'м', 'н', 'о', 'п', 'р', 'с', 'т', 'у', 'ф', 'х', 'ц', 'ч', 'ш', 'щ', 'ь', 'ю', 'я')); - public static final ArrayList UKR_UPPER = new ArrayList<>(Arrays.asList( + private static ArrayList UKR_UPPER = new ArrayList<>(Arrays.asList( 'А', 'Б', 'В', 'Г', 'Ґ', 'Д', 'Е', 'Є', 'Ж', 'З', 'И', 'І', 'Ї', 'Й', 'К', 'Л', 'М', 'Н', 'О', 'П', 'Р', 'С', 'Т', 'У', 'Ф', 'Х', 'Ц', 'Ч', 'Ш', 'Щ', 'Ь', 'Ю', 'Я')); + + public ArrayList getEngLower(){ + return ENG_LOWER; + } + public void setEngLower(ArrayList ENG_LOWER){ + Constants.ENG_LOWER = ENG_LOWER; + } + public ArrayList getEngUpper(){ + return ENG_UPPER; + } + public void setEngUpper(ArrayList ENG_UPPER){ + Constants.ENG_UPPER = ENG_UPPER; + } + public ArrayList getUkrLower(){ + return UKR_LOWER; + } + public void setUkrLower(ArrayList UKR_LOWER){ + Constants.UKR_LOWER = UKR_LOWER; + } + public ArrayList getUkrUpper(){ + return UKR_UPPER; + } + public void setUkrUpper(ArrayList UKR_UPPER){ + Constants.UKR_UPPER = UKR_UPPER; + } } diff --git a/src/main/java/ua/com/javarush/gnew/Dictionary/Dictionary.java b/src/main/java/ua/com/javarush/gnew/Dictionary/Dictionary.java index c02df8b..c85b3f3 100644 --- a/src/main/java/ua/com/javarush/gnew/Dictionary/Dictionary.java +++ b/src/main/java/ua/com/javarush/gnew/Dictionary/Dictionary.java @@ -1,8 +1,27 @@ package ua.com.javarush.gnew.Dictionary; + + public class Dictionary { - public static final String[] dictionary = new String[]{"take","or","for","of","as","his","that","he","was","for","on","are","with","they","be","at","by","word","have","play","my","world","there","those","victory","is","not","to","in","the"}; + private static String[] dictionary = new String[]{"take", "or", "for", "of", "as", "his", "that", "he", "was", "for", "on", "are", "with", "they", "be", "at", "by", "word", "have", "play", "my", "world", "there", "those", "victory", "is", "not", "to", "in", "the"}; + + private static String[] dictionaryUKR = new String[]{"Ми", "всі", "щось", "Привіт", "хто", "що", "коли", "слово", "ти", "він", "вона", "воно", "вони", "йому", "робить", "працює", "каже", "розмовляє", "співає", "чує", "що робить", "збирає", "поле", "був", "була", "ні", "так", "тому що"}; + + public String[] getDictionary() { + return dictionary; + } - public static final String[] dictionaryUKR = new String[]{"Ми", "всі", "щось","Привіт","хто","що","коли","слово","ти","він","вона","воно","вони","йому","робить","працює","каже","розмовляє","співає","чує","що робить","збирає","поле","був","була","ні","так","тому що"}; + public void setDictionary(String[] dictionary) { + Dictionary.dictionary = dictionary; } + public String[] getDictionaryUKR() { + return dictionaryUKR; + } + + public void setEngUpper(String[] dictionaryUKR) { + Dictionary.dictionaryUKR = dictionaryUKR; + } +} + + diff --git a/src/main/java/ua/com/javarush/gnew/Main.java b/src/main/java/ua/com/javarush/gnew/Main.java index 2ebee7d..6254b44 100644 --- a/src/main/java/ua/com/javarush/gnew/Main.java +++ b/src/main/java/ua/com/javarush/gnew/Main.java @@ -2,6 +2,7 @@ +import ua.com.javarush.gnew.Dictionary.Dictionary; import ua.com.javarush.gnew.crypt.code.Cryptanalyzer; import ua.com.javarush.gnew.crypt.code.RunBruteforce; import ua.com.javarush.gnew.file.FileManager; @@ -11,8 +12,6 @@ import java.nio.file.Path; -import static ua.com.javarush.gnew.Dictionary.Dictionary.dictionary; -import static ua.com.javarush.gnew.Dictionary.Dictionary.dictionaryUKR; public class Main { public static void main(String[] args) { @@ -21,6 +20,7 @@ public static void main(String[] args) { FileManager fileManager = new FileManager(); ArgumentsParser argumentsParser = new ArgumentsParser(); RunOptions runOptions = argumentsParser.parse(args); + Dictionary dictionary = new Dictionary(); try { if (runOptions.getCommand() == Command.ENCRYPT) { String content = fileManager.read(runOptions.getFilePath()); @@ -40,9 +40,9 @@ public static void main(String[] args) { fileManager.write(newFilePath, encryptedContent); } else if (runOptions.getCommand() == Command.BRUTEFORCE) { String content = fileManager.read(runOptions.getFilePath()); - String encryptedContent = runBruteforce.bruteforce(content,dictionary, dictionaryUKR); + String encryptedContent = runBruteforce.bruteforce(content,dictionary.getDictionary(), dictionary.getDictionaryUKR()); String fileName = runOptions.getFilePath().getFileName().toString(); - String key = runBruteforce.getKey(content, dictionary, dictionaryUKR).replace("Key: ", ""); + String key = runBruteforce.getKey(content, dictionary.getDictionary(), dictionary.getDictionaryUKR()).replace("Key: ", ""); String newFileName = fileName.substring(0, fileName.length() - 4) + " [DECRYPTED Key -" + key + "].txt"; Path newFilePath = runOptions.getFilePath().resolveSibling(newFileName); diff --git a/src/main/java/ua/com/javarush/gnew/crypt/code/Cryptanalyzer.java b/src/main/java/ua/com/javarush/gnew/crypt/code/Cryptanalyzer.java index c9d417f..e982eae 100644 --- a/src/main/java/ua/com/javarush/gnew/crypt/code/Cryptanalyzer.java +++ b/src/main/java/ua/com/javarush/gnew/crypt/code/Cryptanalyzer.java @@ -1,21 +1,23 @@ package ua.com.javarush.gnew.crypt.code; +import ua.com.javarush.gnew.Constants.Constants; + import java.util.ArrayList; import java.util.Collections; -import static ua.com.javarush.gnew.Constants.Constants.*; public class Cryptanalyzer { public String encryption(String str, int key) { + Constants constants = new Constants(); key = Math.negateExact(key); - ArrayList ENG_LOWER_MOD = new ArrayList<>(ENG_LOWER); - ArrayList UKR_LOWER_MOD = new ArrayList<>(UKR_LOWER); + ArrayList ENG_LOWER_MOD = new ArrayList<>(constants.getEngLower()); + ArrayList UKR_LOWER_MOD = new ArrayList<>(constants.getUkrLower()); Collections.rotate(ENG_LOWER_MOD, key); Collections.rotate(UKR_LOWER_MOD, key); - ArrayList ENG_UPPER_MOD = new ArrayList<>(ENG_UPPER); - ArrayList UKR_UPPER_MOD = new ArrayList<>(UKR_UPPER); + ArrayList ENG_UPPER_MOD = new ArrayList<>(constants.getEngUpper()); + ArrayList UKR_UPPER_MOD = new ArrayList<>(constants.getUkrUpper()); Collections.rotate(ENG_UPPER_MOD, key); Collections.rotate(UKR_UPPER_MOD, key); @@ -24,14 +26,14 @@ public String encryption(String str, int key) { for (char symbol : array) { if (Character.isLowerCase(symbol)) { - int originalIndex = ENG_LOWER.indexOf(symbol); + int originalIndex = constants.getEngLower().indexOf(symbol); if (originalIndex != -1) { Character encrypted = ENG_LOWER_MOD.get(originalIndex); builder.append(encrypted); continue; } - originalIndex = UKR_LOWER.indexOf(symbol); + originalIndex = constants.getUkrLower().indexOf(symbol); if (originalIndex != -1) { Character encrypted = UKR_LOWER_MOD.get(originalIndex); builder.append(encrypted); @@ -40,14 +42,14 @@ public String encryption(String str, int key) { } } else if (Character.isUpperCase(symbol)) { - int originalIndex = ENG_UPPER.indexOf(symbol); + int originalIndex = constants.getEngUpper().indexOf(symbol); if (originalIndex != -1) { Character encrypted = ENG_UPPER_MOD.get(originalIndex); builder.append(encrypted); continue; } - originalIndex = UKR_UPPER.indexOf(symbol); + originalIndex = constants.getUkrUpper().indexOf(symbol); if (originalIndex != -1) { Character encrypted = UKR_UPPER_MOD.get(originalIndex); builder.append(encrypted); diff --git a/src/main/java/ua/com/javarush/gnew/crypt/code/RunBruteforce.java b/src/main/java/ua/com/javarush/gnew/crypt/code/RunBruteforce.java index 2de17fd..63ca8b0 100644 --- a/src/main/java/ua/com/javarush/gnew/crypt/code/RunBruteforce.java +++ b/src/main/java/ua/com/javarush/gnew/crypt/code/RunBruteforce.java @@ -1,7 +1,7 @@ package ua.com.javarush.gnew.crypt.code; -import static ua.com.javarush.gnew.Constants.Constants.*; +import ua.com.javarush.gnew.Constants.Constants; public class RunBruteforce { @@ -11,8 +11,9 @@ public String bruteforce(String str, String[] dictionary, String[] dictionaryUKR int maxMatches = 0; StringBuilder builder; Cryptanalyzer crypt = new Cryptanalyzer(); + Constants constants = new Constants(); - for (int key = 0; key <= ENG_LOWER.size(); key++) { + for (int key = 0; key < constants.getEngLower().size(); key++) { builder = new StringBuilder(crypt.getDecryption(str, key)); String decryptedText = builder.toString(); int matches = countMatches(decryptedText, dictionary); @@ -22,7 +23,7 @@ public String bruteforce(String str, String[] dictionary, String[] dictionaryUKR bestMatch = decryptedText; } } - for (int key = 0; key <= UKR_LOWER.size(); key++) { + for (int key = 0; key <= constants.getUkrLower().size(); key++) { builder = new StringBuilder(crypt.getDecryption(str, key)); String decryptedText = builder.toString(); int matches = countMatches(decryptedText, dictionaryUKR); @@ -51,8 +52,9 @@ public String getKey(String str, String[] dictionary, String[] dictionaryUKR) { String keyResult = null; StringBuilder builder; Cryptanalyzer crypt = new Cryptanalyzer(); + Constants constants = new Constants(); - for (int key = 0; key < ENG_LOWER.size(); key++) { + for (int key = 0; key < constants.getEngLower().size(); key++) { builder = new StringBuilder(crypt.getDecryption(str, key)); String decryptedText = builder.toString(); int matches = countMatches(decryptedText, dictionary); @@ -63,7 +65,7 @@ public String getKey(String str, String[] dictionary, String[] dictionaryUKR) { } } - for (int key = 0; key < UKR_LOWER.size(); key++) { + for (int key = 0; key < constants.getUkrLower().size(); key++) { builder = new StringBuilder(crypt.getDecryption(str, key)); String decryptedText = builder.toString(); int matches = countMatches(decryptedText, dictionaryUKR); From af743aabd37afdbef13031e5e590cb8ed3f733cc Mon Sep 17 00:00:00 2001 From: Denys Date: Sat, 21 Sep 2024 20:40:42 +0300 Subject: [PATCH 20/21] Add GUI(Swing) --- .../javarush/gnew/CLI/CryptAnalyzerGUI.java | 107 ++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 src/main/java/ua/com/javarush/gnew/CLI/CryptAnalyzerGUI.java diff --git a/src/main/java/ua/com/javarush/gnew/CLI/CryptAnalyzerGUI.java b/src/main/java/ua/com/javarush/gnew/CLI/CryptAnalyzerGUI.java new file mode 100644 index 0000000..237f7ca --- /dev/null +++ b/src/main/java/ua/com/javarush/gnew/CLI/CryptAnalyzerGUI.java @@ -0,0 +1,107 @@ +package ua.com.javarush.gnew.CLI; + +import ua.com.javarush.gnew.Dictionary.Dictionary; +import ua.com.javarush.gnew.crypt.code.Cryptanalyzer; +import ua.com.javarush.gnew.crypt.code.RunBruteforce; +import ua.com.javarush.gnew.file.FileManager; +import ua.com.javarush.gnew.runner.Command; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.io.IOException; +import java.nio.file.Path; + +public class CryptAnalyzerGUI { + private static final Cryptanalyzer cryptanalyzer = new Cryptanalyzer(); + private static final RunBruteforce runBruteforce = new RunBruteforce(); + private static final FileManager fileManager = new FileManager(); + private static final Dictionary dictionary = new Dictionary(); + + public static void main(String[] args) { + JFrame frame = new JFrame("Cryptanalyzer"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setSize(500, 400); + + JPanel panel = new JPanel(); + panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); + + JLabel commandLabel = new JLabel("Выберите команду:"); + panel.add(commandLabel); + + String[] commands = {"ENCRYPT", "DECRYPT", "BRUTEFORCE"}; + JComboBox commandBox = new JComboBox<>(commands); + panel.add(commandBox); + + JLabel fileLabel = new JLabel("Выберите файл:"); + JTextField filePathField = new JTextField(20); + JButton fileButton = new JButton("Выбрать файл"); + fileButton.addActionListener(e -> { + JFileChooser fileChooser = new JFileChooser(); + int returnValue = fileChooser.showOpenDialog(null); + if (returnValue == JFileChooser.APPROVE_OPTION) { + filePathField.setText(fileChooser.getSelectedFile().getPath()); + } + }); + + JPanel filePanel = new JPanel(); + filePanel.add(filePathField); + filePanel.add(fileButton); + panel.add(fileLabel); + panel.add(filePanel); + + JLabel keyLabel = new JLabel("Введите ключ (только для ENCRYPT и DECRYPT):"); + JTextField keyField = new JTextField(10); + panel.add(keyLabel); + panel.add(keyField); + + JButton executeButton = new JButton("Выполнить"); + panel.add(executeButton); + + JTextArea resultArea = new JTextArea(10, 30); + resultArea.setEditable(false); + JScrollPane scrollPane = new JScrollPane(resultArea); + panel.add(scrollPane); + + executeButton.addActionListener((ActionEvent e) -> { + try { + String selectedCommand = (String) commandBox.getSelectedItem(); + Path filePath = Path.of(filePathField.getText()); + String content = fileManager.read(filePath); + + if (selectedCommand.equals("ENCRYPT")) { + int key = Integer.parseInt(keyField.getText()); + String encryptedContent = cryptanalyzer.encryption(content, key); + String newFileName = filePath.getFileName().toString().replace(".txt", " [ENCRYPTED].txt"); + Path newFilePath = filePath.resolveSibling(newFileName); + fileManager.write(newFilePath, encryptedContent); + resultArea.setText("Файл успешно зашифрован: " + newFilePath); + } else if (selectedCommand.equals("DECRYPT")) { + int key = Integer.parseInt(keyField.getText()); + String decryptedContent = cryptanalyzer.decryption(content, key); + String newFileName = filePath.getFileName().toString().replace(".txt", " [DECRYPTED].txt"); + Path newFilePath = filePath.resolveSibling(newFileName); + fileManager.write(newFilePath, decryptedContent); + resultArea.setText("Файл успешно расшифрован: " + newFilePath); + } else if (selectedCommand.equals("BRUTEFORCE")) { + String decryptedContent = runBruteforce.bruteforce(content, dictionary.getDictionary(), dictionary.getDictionaryUKR()); + String key = runBruteforce.getKey(content, dictionary.getDictionary(), dictionary.getDictionaryUKR()).replace("Key: ", ""); + String newFileName = filePath.getFileName().toString().replace(".txt", " [DECRYPTED Key-" + key + "].txt"); + Path newFilePath = filePath.resolveSibling(newFileName); + fileManager.write(newFilePath, decryptedContent); + resultArea.setText("Брутфорс выполнен. Найден ключ: " + key + "\nФайл сохранен как: " + newFilePath); + } + } catch (IOException ex) { + resultArea.setText("Ошибка чтения/записи файла: " + ex.getMessage()); + } catch (NumberFormatException ex) { + resultArea.setText("Неправильный формат ключа: " + ex.getMessage()); + } catch (Exception ex) { + resultArea.setText("Произошла ошибка: " + ex.getMessage()); + } + }); + + frame.add(panel); + frame.setVisible(true); + } +} + From 0e72d5b77c8ba9be96aa8edf693bb10bc4d2f968 Mon Sep 17 00:00:00 2001 From: Denys Date: Mon, 6 Jan 2025 17:47:07 +0200 Subject: [PATCH 21/21] Add GUI(Swing) --- out/artifacts/GNEW_M1_FP_jar/GNEW-M1-FP.jar | Bin 13620 -> 17118 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/out/artifacts/GNEW_M1_FP_jar/GNEW-M1-FP.jar b/out/artifacts/GNEW_M1_FP_jar/GNEW-M1-FP.jar index 028287bb45d4c1c6f8c583b1354405d24603d3db..ce960e3f45303286f96c6c1f32763ec11294adc7 100644 GIT binary patch delta 11837 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 LD#{6=KPvw}d8-PE delta 8436 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 Ci=Ws4