-
Notifications
You must be signed in to change notification settings - Fork 47
Минка - 2 tasks complete. #26
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
113d43d
a1c118a
fc71552
ae747a1
01253be
b2148b6
d16f5c3
8d40e13
f642519
7ea25d5
14c2940
07d22a7
cca58af
99d6f77
a1bc5e0
cbb5f7b
1f0f150
9a96484
3470017
35b7445
c53bb95
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| package com.javarush.minka; | ||
|
|
||
| import java.util.HashMap; | ||
| import java.util.Map; | ||
|
|
||
| public class Alphabet { | ||
| private Alphabet() { | ||
| } | ||
|
|
||
| private static final String en = "QWERTYUIOPASDFGHJKLZXCVBNM"; | ||
| private static final String rus = "ЙЦУКЕНГШЩЗХЪЭЖДЛОРПАВЫФЯЧСМИТЬБЮ"; | ||
| private static final String numbers = "1234567890"; | ||
| private static final String symbols = "\n.,”’\":;-!? ()<>"; | ||
|
|
||
| public static final char[] chars = (rus + rus.toLowerCase() + | ||
| en + en.toLowerCase() + | ||
| numbers + symbols | ||
| ).toCharArray(); | ||
|
|
||
| public static final Map<Character, Integer> indexLetter = new HashMap<>(); | ||
|
|
||
| static { | ||
| for (int i = 0; i < chars.length; i++) { | ||
| indexLetter.put(chars[i], i); | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| package com.javarush.minka; | ||
|
|
||
| import java.util.Scanner; | ||
|
|
||
| public class ConsoleRunner { | ||
| public static void main(String[] args) { | ||
| Scanner scanner = new Scanner(System.in); | ||
|
|
||
| Menu menu = new Menu(); | ||
| DefaultFilePathBuilder filePathBuilder = new DefaultFilePathBuilder(); | ||
| InputParamsReader inputParamsReader = new InputParamsReader(scanner, filePathBuilder); | ||
| CryptoProcessor cryptoProcessor = new CryptoProcessor(); | ||
| CryptoApp cryptoApp = new CryptoApp(cryptoProcessor, menu, inputParamsReader, scanner); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Тут всё верно |
||
|
|
||
| cryptoApp.run(); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| package com.javarush.minka; | ||
|
|
||
| import java.io.*; | ||
|
|
||
| public abstract class CryptoAction { | ||
| public void process(String inputFilePath, String outputFilePath, int key) { | ||
| try ( | ||
| BufferedReader reader = new BufferedReader(new FileReader(inputFilePath)); | ||
| BufferedWriter writer = new BufferedWriter(new FileWriter(outputFilePath)) | ||
| ) { | ||
| int symbol; | ||
|
|
||
| while ((symbol = reader.read()) != -1) { | ||
| char c = (char) symbol; | ||
| char changed = transform(c, key); | ||
| writer.write(changed); | ||
| } | ||
| } catch (RuntimeException | IOException e) { | ||
| throw new RuntimeException(e); | ||
| } | ||
| } | ||
|
|
||
| protected abstract char transform(char c, int key); | ||
|
|
||
| protected Integer getIndex(char c) { | ||
| return Alphabet.indexLetter.get(c); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| package com.javarush.minka; | ||
|
|
||
| import java.io.IOException; | ||
| import java.util.Scanner; | ||
|
|
||
| public class CryptoApp { | ||
| private final CryptoProcessor cryptoProcessor; | ||
| private final Menu menu; | ||
| private final InputParamsReader inputParamsReader; | ||
| private final Scanner scanner; | ||
|
|
||
| public CryptoApp(CryptoProcessor cryptoProcessor, Menu menu, InputParamsReader inputParamsReader, Scanner scanner) { | ||
| this.cryptoProcessor = cryptoProcessor; | ||
| this.menu = menu; | ||
| this.inputParamsReader = inputParamsReader; | ||
| this.scanner = scanner; | ||
| } | ||
|
|
||
| public void run() { | ||
| while (true) { | ||
| int choice = menu.showMainMenu(scanner); | ||
|
|
||
| if (choice == 1) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Числам можно дать какие-нибудь имена в виде констант, это должно повысить читаемость кода |
||
| String inputFile = inputParamsReader.readInputFile(); | ||
| String outputFile = inputParamsReader.readOutputFile(); | ||
| int key = inputParamsReader.readKey(); | ||
|
|
||
| try { | ||
| cryptoProcessor.encrypt(inputFile, outputFile, key); | ||
| System.out.println("Шифрование завершено! Результат: " + outputFile); | ||
| } catch (RuntimeException | IOException e) { | ||
| System.out.println("Ошибка: " + e.getMessage()); | ||
| } | ||
| } else if (choice == 2) { | ||
| String inputFile = inputParamsReader.readInputFile(); | ||
| String outputFile = inputParamsReader.readOutputFile(); | ||
| int key = inputParamsReader.readKey(); | ||
|
|
||
| try { | ||
| cryptoProcessor.decrypt(inputFile, outputFile, key); | ||
| System.out.println("Дешифрование завершено! Результат: " + outputFile); | ||
| } catch (RuntimeException | IOException e) { | ||
| System.out.println("Ошибка " + e.getMessage()); | ||
| } | ||
| } else if (choice == 3) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. С учётом того что команд всего три то построения логики на основе разветвлений выглядит приемлемо, однако в реальных приложениях команд сотни и более, поэтому полезно сразу формировать их хранения в виде карты. Такое решение более легко масштабируется |
||
| System.out.println("Выход."); | ||
| break; | ||
| } else { | ||
| System.out.println("Ошибка: некорректный выбор."); | ||
| } | ||
| System.out.println(); | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| package com.javarush.minka; | ||
|
|
||
| import java.io.IOException; | ||
|
|
||
| public class CryptoProcessor { | ||
| public void encrypt(String inputFile, String outputFile, int key) throws IOException { | ||
| CryptoAction action = new Encrypt(); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Этот объект никогда не будет изменяться, поэтому лучше его вынести в поле и создавать только однажды в момент создания криптопроцессора |
||
| action.process(inputFile, outputFile, key); | ||
| } | ||
|
|
||
| public void decrypt(String inputFile, String outputFile, int key) throws IOException { | ||
| CryptoAction action = new Decrypt(); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. То же самое |
||
| action.process(inputFile, outputFile, key); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| package com.javarush.minka; | ||
|
|
||
| public class Decrypt extends CryptoAction { | ||
| @Override | ||
| protected char transform(char c, int key) { | ||
| Integer index = getIndex(c); | ||
| if (index == null) { | ||
| return c; | ||
| } | ||
| int newIndex = (index - key) % Alphabet.chars.length; | ||
| if (newIndex < 0) { | ||
| newIndex += Alphabet.chars.length; | ||
| } | ||
| return Alphabet.chars[newIndex]; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| package com.javarush.minka; | ||
|
|
||
| import java.io.File; | ||
|
|
||
| public class DefaultFilePathBuilder { | ||
| public String buildAbsolutePath(String fileName) { | ||
| return new File(fileName).getAbsolutePath(); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| package com.javarush.minka; | ||
|
|
||
| public class Encrypt extends CryptoAction { | ||
| @Override | ||
| protected char transform(char c, int key) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Кот в классах шифрования и дешифрования очень похож и по сути может быть вынесен в абстракцию |
||
| Integer index = getIndex(c); | ||
| if (index == null) { | ||
| return c; | ||
| } | ||
| int newIndex = (index + key) % Alphabet.chars.length; | ||
| if (newIndex < 0) { | ||
| newIndex += Alphabet.chars.length; | ||
| } | ||
| return Alphabet.chars[newIndex]; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| package com.javarush.minka; | ||
|
|
||
| import java.io.File; | ||
| import java.util.Scanner; | ||
|
|
||
| public class InputParamsReader { | ||
| private static final String DEFAULT_DIRECTORY = System.getProperty("user.dir") + | ||
| File.separator + "text" + File.separator; | ||
| private static final String DEFAULT_SOURCE_FILE = DEFAULT_DIRECTORY + "text.txt"; | ||
| private static final String DEFAULT_OUTPUT_FILE = DEFAULT_DIRECTORY + "output.txt"; | ||
| private final Scanner scanner; | ||
| private final DefaultFilePathBuilder filePathBuilder; | ||
|
|
||
| public InputParamsReader(Scanner scanner, DefaultFilePathBuilder filePathBuilder) { | ||
| this.scanner = scanner; | ||
| this.filePathBuilder = filePathBuilder; | ||
| } | ||
|
|
||
| public String readInputFile() { | ||
| System.out.print("Исходный файл по умолчанию " + DEFAULT_SOURCE_FILE + " (y/n): "); | ||
| String useDefault = scanner.nextLine(); | ||
| if (useDefault.equalsIgnoreCase("y")) { | ||
| return filePathBuilder.buildAbsolutePath(DEFAULT_SOURCE_FILE); | ||
| } | ||
| System.out.print("Введите абсолютный путь к исходному файлу: "); | ||
| return scanner.nextLine(); | ||
| } | ||
|
|
||
| public String readOutputFile() { | ||
| System.out.print("Результирующий Файл по умолчанию " + DEFAULT_OUTPUT_FILE + " (y/n): "); | ||
| String useDefault = scanner.nextLine(); | ||
| if (useDefault.equalsIgnoreCase("y")) { | ||
| return filePathBuilder.buildAbsolutePath(DEFAULT_OUTPUT_FILE); | ||
| } | ||
| System.out.print("Введите абсолютный путь к файлу для вывода результатов: "); | ||
| return scanner.nextLine(); | ||
| } | ||
|
|
||
| public int readKey() { | ||
| System.out.print("Введите числовой ключ (положительное значение): "); | ||
| while (true) { | ||
| String input = scanner.nextLine(); | ||
| try { | ||
| return Integer.parseInt(input); | ||
| } catch (RuntimeException e) { | ||
| System.out.print("Введённое значение ключа не корректно. Попробуйте еще раз: "); | ||
| } | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| package com.javarush.minka; | ||
|
|
||
| import java.util.Scanner; | ||
|
|
||
| public class Menu { | ||
| public int showMainMenu(Scanner scanner) { | ||
| System.out.println("-".repeat(70) + | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Тут наверное пригодились тройные кавычки |
||
| "\u001b[32m" + "\nПрограмма шифрования и дешифрования файлов на основании шифра Цезаря."); | ||
| System.out.println("\t1. Шифрование"); | ||
| System.out.println("\t2. Дешифрование"); | ||
| System.out.println("\t3. Выход"); | ||
| System.out.print("Выберите действие: " + "\u001b[0m\n" + "-".repeat(70) + "\n"); | ||
| String input = scanner.nextLine(); | ||
| try { | ||
| return Integer.parseInt(input); | ||
| } catch (Exception e) { | ||
| return -1; | ||
| } | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
То что приложение небольшое совсем не означает что ему не нужны пакеты, в реальных приложениях классов всё равно очень много, и поэтому привычка размещать все по пакетам очень хорошая