diff --git a/src/main/java/com/javarush/golikov/Application.java b/src/main/java/com/javarush/golikov/Application.java new file mode 100644 index 0000000..63924bf --- /dev/null +++ b/src/main/java/com/javarush/golikov/Application.java @@ -0,0 +1,16 @@ +package com.javarush.golikov; + +import com.javarush.golikov.controller.Controller; +import com.javarush.golikov.entite.Result; +import com.javarush.golikov.view.ShowMenu; + +public class Application { + private final Controller controller = new Controller(); + private final ShowMenu showMenu = new ShowMenu(); + + public Result run() { + int menuIndex = showMenu.getMenuItem(); + String[] parametrises = showMenu.getParameterises(menuIndex == 0 || menuIndex == 1); + return controller.doAction(menuIndex, parametrises); + } +} diff --git a/src/main/java/com/javarush/golikov/ConsoleRunner.java b/src/main/java/com/javarush/golikov/ConsoleRunner.java new file mode 100644 index 0000000..b5f6ff9 --- /dev/null +++ b/src/main/java/com/javarush/golikov/ConsoleRunner.java @@ -0,0 +1,11 @@ +package com.javarush.golikov; + +import com.javarush.golikov.entite.Result; + +public class ConsoleRunner { + public static void main(String[] args) { + Application application = new Application(); + Result result = application.run(); + System.out.println(result); + } +} diff --git a/src/main/java/com/javarush/golikov/constatnts/Constants.java b/src/main/java/com/javarush/golikov/constatnts/Constants.java new file mode 100644 index 0000000..5b5adf6 --- /dev/null +++ b/src/main/java/com/javarush/golikov/constatnts/Constants.java @@ -0,0 +1,19 @@ +package com.javarush.golikov.constatnts; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +public class Constants { + private static final String ruAlphabet = "АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ"; + private static final String specialCharacters = "\n.,\":-!? "; + + public static final char[] ALPHABET = (ruAlphabet.toLowerCase() + specialCharacters).toCharArray(); + public static final String DEFAULT_FOLDER = System.getProperty("user.dir") + File.separator + "text" + File.separator; + + public static final List ALPHABET_LIST = new ArrayList<>(); + + static { + for(Character simbol : ALPHABET) ALPHABET_LIST.add(simbol); + } +} diff --git a/src/main/java/com/javarush/golikov/controller/Actions.java b/src/main/java/com/javarush/golikov/controller/Actions.java new file mode 100644 index 0000000..92c4063 --- /dev/null +++ b/src/main/java/com/javarush/golikov/controller/Actions.java @@ -0,0 +1,31 @@ +package com.javarush.golikov.controller; + +import com.javarush.golikov.exception.ApplicationExceptions; +import com.javarush.golikov.menuComands.BruteForce; +import com.javarush.golikov.menuComands.MenuCommands; +import com.javarush.golikov.menuComands.Decoding; +import com.javarush.golikov.menuComands.Encryption; + +import java.util.HashMap; +import java.util.Map; + +public class Actions { + + private final Map actionMap = new HashMap<>(); + + public Actions() { + actionMap.put(0, new Encryption()); + actionMap.put(1, new Decoding()); + actionMap.put(2, new BruteForce()); + } + + public MenuCommands findAction(int actionIndex) { + if (actionMap.containsKey(actionIndex)) { + try { + return actionMap.get(actionIndex); + } catch (IllegalArgumentException e) { + throw new ApplicationExceptions("Пункт меню не реализован!", e); + } + } else throw new ApplicationExceptions("Пункт меню не реализован!"); + } +} diff --git a/src/main/java/com/javarush/golikov/controller/Controller.java b/src/main/java/com/javarush/golikov/controller/Controller.java new file mode 100644 index 0000000..661f15c --- /dev/null +++ b/src/main/java/com/javarush/golikov/controller/Controller.java @@ -0,0 +1,18 @@ +package com.javarush.golikov.controller; + +import com.javarush.golikov.entite.Result; +import com.javarush.golikov.exception.ApplicationExceptions; +import com.javarush.golikov.menuComands.MenuCommands; + + +public class Controller { + public Result doAction(int actionNumber, String[] parametrises) { + Actions actions = new Actions(); + try{ + MenuCommands menuCommands = actions.findAction(actionNumber); + return menuCommands.execute(parametrises); + } catch (IllegalArgumentException | ApplicationExceptions e) { + return new Result(e.getMessage(), "Error"); + } + } +} diff --git a/src/main/java/com/javarush/golikov/entite/Result.java b/src/main/java/com/javarush/golikov/entite/Result.java new file mode 100644 index 0000000..54a6370 --- /dev/null +++ b/src/main/java/com/javarush/golikov/entite/Result.java @@ -0,0 +1,12 @@ +package com.javarush.golikov.entite; + +public record Result(String message, String resultCode) { + + @Override + public String toString() { + return "Result{" + + "message='" + message + '\'' + + ", resultCode='" + resultCode + '\'' + + '}'; + } +} diff --git a/src/main/java/com/javarush/golikov/exception/ApplicationExceptions.java b/src/main/java/com/javarush/golikov/exception/ApplicationExceptions.java new file mode 100644 index 0000000..56a46b6 --- /dev/null +++ b/src/main/java/com/javarush/golikov/exception/ApplicationExceptions.java @@ -0,0 +1,13 @@ +package com.javarush.golikov.exception; + +public class ApplicationExceptions extends RuntimeException { + + public ApplicationExceptions(String message) { + super(message); + } + + public ApplicationExceptions(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/src/main/java/com/javarush/golikov/menuComands/BruteForce.java b/src/main/java/com/javarush/golikov/menuComands/BruteForce.java new file mode 100644 index 0000000..f89fe1a --- /dev/null +++ b/src/main/java/com/javarush/golikov/menuComands/BruteForce.java @@ -0,0 +1,56 @@ +package com.javarush.golikov.menuComands; + +import com.javarush.golikov.constatnts.Constants; +import com.javarush.golikov.entite.Result; +import com.javarush.golikov.exception.ApplicationExceptions; + +import java.io.BufferedReader; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; + +public class BruteForce extends Commands { + @Override + public Result execute(String[] parametrises) { + String source = parametrises[0]; + if (Files.isDirectory(Path.of(source))) { + source += "output.txt"; + } + String target = parametrises[1]; + if (Files.isDirectory(Path.of(target))) { + target += "bfresult.txt"; + } + int bestKey = 0; + int bestSpaceCount = 0; + char space = ' '; + for (int key = 0; key < Constants.ALPHABET.length; key++) { + int spaceCount = countCharInFileWithKey(source, key, space); + if (spaceCount > bestSpaceCount) { + bestSpaceCount = spaceCount; + bestKey = key; + } + } + return doCommand(source, target, bestKey); + } + + private int countCharInFileWithKey(String encryptedFilename, int key, char fixChar) { + int spaceCount = 0; + Path path = Path.of(encryptedFilename); + try (BufferedReader reader = Files.newBufferedReader(path)) { + int value; + while ((value = reader.read()) > -1) { + char character = (char) value; + if (Constants.ALPHABET_LIST.contains(character)) { + int index = Constants.ALPHABET_LIST.indexOf(character); + index = (index + key + Constants.ALPHABET.length) % Constants.ALPHABET.length; + if (Constants.ALPHABET[index] == fixChar) { + spaceCount++; + } + } + } + } catch (IOException e) { + throw new ApplicationExceptions("Файл не найден" + encryptedFilename, e); + } + return spaceCount; + } +} diff --git a/src/main/java/com/javarush/golikov/menuComands/Commands.java b/src/main/java/com/javarush/golikov/menuComands/Commands.java new file mode 100644 index 0000000..20e89fe --- /dev/null +++ b/src/main/java/com/javarush/golikov/menuComands/Commands.java @@ -0,0 +1,38 @@ +package com.javarush.golikov.menuComands; + +import com.javarush.golikov.constatnts.Constants; +import com.javarush.golikov.entite.Result; +import com.javarush.golikov.exception.ApplicationExceptions; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; + +public abstract class Commands implements MenuCommands { + public Result doCommand(String source, String target, int key) { + Path sourceFile = Path.of(source); + Path targetFile = Path.of(target); + + try (BufferedReader fileReader = Files.newBufferedReader(sourceFile); + BufferedWriter fileWriter = Files.newBufferedWriter(targetFile)) { + int value; + int length = Constants.ALPHABET.length; + while ((value = fileReader.read()) > -1) { + char character = (char) value; + character = Character.toLowerCase(character); + if (Constants.ALPHABET_LIST.contains(character)) { + int index = Constants.ALPHABET_LIST.indexOf(character); + index = (index + key + Math.abs(key) * length) % length; + fileWriter.write(Constants.ALPHABET[index]); + } else if (character == '\n') { + fileWriter.write(character); + } + } + } catch (IOException e) { + throw new ApplicationExceptions("Файл не найден" + e.getMessage(), e); + } + return new Result(this.getClass().getSimpleName(), "Ok"); + } +} diff --git a/src/main/java/com/javarush/golikov/menuComands/Decoding.java b/src/main/java/com/javarush/golikov/menuComands/Decoding.java new file mode 100644 index 0000000..dc16723 --- /dev/null +++ b/src/main/java/com/javarush/golikov/menuComands/Decoding.java @@ -0,0 +1,29 @@ +package com.javarush.golikov.menuComands; + +import com.javarush.golikov.entite.Result; +import com.javarush.golikov.exception.ApplicationExceptions; + +import java.nio.file.Files; +import java.nio.file.Path; + +public class Decoding extends Commands { + + @Override + public Result execute(String[] parametrises) { + String source = parametrises[0]; + if (Files.isDirectory(Path.of(source))) { + source += "output.txt"; + } + String target = parametrises[1]; + if (Files.isDirectory(Path.of(target))) { + target += "decoding.txt"; + } + int key; + try { + key = Integer.parseInt(parametrises[2]); + } catch (NumberFormatException e) { + throw new ApplicationExceptions("Неверный ключ"); + } + return doCommand(source, target, key * -1); + } +} diff --git a/src/main/java/com/javarush/golikov/menuComands/Encryption.java b/src/main/java/com/javarush/golikov/menuComands/Encryption.java new file mode 100644 index 0000000..807902a --- /dev/null +++ b/src/main/java/com/javarush/golikov/menuComands/Encryption.java @@ -0,0 +1,29 @@ +package com.javarush.golikov.menuComands; + +import com.javarush.golikov.entite.Result; +import com.javarush.golikov.exception.ApplicationExceptions; + +import java.nio.file.Files; +import java.nio.file.Path; + +public class Encryption extends Commands { + + @Override + public Result execute(String[] parametrises) { + String source = parametrises[0]; + if (Files.isDirectory(Path.of(source))) { + source += "text.txt"; + } + String target = parametrises[1]; + if (Files.isDirectory(Path.of(target))) { + target += "output.txt"; + } + int key; + try{ + key = Integer.parseInt(parametrises[2]); + } catch(NumberFormatException e){ + throw new ApplicationExceptions("Неверный ключ"); + } + return doCommand(source, target, key); + } +} diff --git a/src/main/java/com/javarush/golikov/menuComands/MenuCommands.java b/src/main/java/com/javarush/golikov/menuComands/MenuCommands.java new file mode 100644 index 0000000..60fd277 --- /dev/null +++ b/src/main/java/com/javarush/golikov/menuComands/MenuCommands.java @@ -0,0 +1,7 @@ +package com.javarush.golikov.menuComands; + +import com.javarush.golikov.entite.Result; + +public interface MenuCommands { + Result execute(String[] parametrises); +} diff --git a/src/main/java/com/javarush/golikov/view/ShowMenu.java b/src/main/java/com/javarush/golikov/view/ShowMenu.java new file mode 100644 index 0000000..f699d2a --- /dev/null +++ b/src/main/java/com/javarush/golikov/view/ShowMenu.java @@ -0,0 +1,52 @@ +package com.javarush.golikov.view; + +import com.javarush.golikov.constatnts.Constants; + +import java.util.Scanner; + + +public class ShowMenu { + private final Scanner scanner = new Scanner(System.in); + + public int getMenuItem() { + int item; + do { + System.out.println("Выберите пункт меню\n" + + """ + 1. Шифрование + 2. Дешифровка + 3. "Brute force" + 4. Анализ + 5. Выход + """ ); + String input = scanner.nextLine(); + item = switch (input) { + case "1" -> 0; + case "2" -> 1; + case "3" -> 2; + case "4" -> 3; + case "5" -> 4; + default -> { + System.out.println("Неверный ввод. Повторите ввод"); + yield -1; + } + }; + } while (item < 0); + return item; + } + + public String[] getParameterises(boolean isKeyNeeded) { + String[] parameterises = new String[3]; + if (isKeyNeeded){ + System.out.println("Введите ключ шифрования/дешифрования"); + parameterises[2] = scanner.nextLine(); + } + System.out.println("Введите путь исходного файла по умолчанию директория пользователя папка text"); + String innFile = scanner.nextLine(); + parameterises[0] = innFile.isEmpty() ? Constants.DEFAULT_FOLDER : innFile; + System.out.println("Введите путь конечного файла по умолчанию директория пользователя папка text"); + String outFile = scanner.nextLine(); + parameterises[1] = outFile.isEmpty() ? Constants.DEFAULT_FOLDER : innFile; + return parameterises; + } +}