Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ target/
!**/src/test/**/out/
*.iml
.idea/

*.class

### Mac OS ###
.DS_Store
Expand Down
84 changes: 84 additions & 0 deletions src/main/java/com/javarush/karpeev/command/CryptText.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package com.javarush.karpeev.command;

import com.javarush.karpeev.constants.Constants;

import java.util.Arrays;

public class CryptText {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TextCryptor? TextCryptoProcessor?

public char[] encrypt(char[] arrayInputText, int key) {
char[] arrayOutputText = new char[arrayInputText.length];
for (int i = 0; i < arrayInputText.length; i++) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Вижу два практически одинаковых метода

if (arrayInputText[i] == '\n') {
arrayOutputText[i] = arrayInputText[i];
continue;
}
for (int j = 0; j < Constants.alphabet.length; j++) {
if (arrayInputText[i] == Constants.alphabet[j]) {
if (j + key > Constants.alphabet.length - 1) {
arrayOutputText[i] = Constants.alphabet[(j + key) % Constants.alphabet.length];
} else {
arrayOutputText[i] = Constants.alphabet[j + key];
}
}
}
}
return arrayOutputText;
}

public char[] decrypt(char[] arrayInputText, int key) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Использовать массив букв обычно намного менее удобно чем строку или стринг билдер

char[] arrayOutputText = new char[arrayInputText.length];
for (int i = 0; i < arrayInputText.length; i++) {
if (arrayInputText[i] == '\n') {
arrayOutputText[i] = arrayInputText[i];
continue;
}
for (int j = 0; j < Constants.alphabet.length; j++) {
if (arrayInputText[i] == Constants.alphabet[j]) {
if (j - key < 0) {
arrayOutputText[i] = Constants.alphabet[Constants.alphabet.length + j - key];
} else {
arrayOutputText[i] = Constants.alphabet[j - key];
}
}
}
}
return arrayOutputText;
}

public int bruteForce(char[] arrayDecodeText) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Три разных по функциям метода расположены в одном классе, лучше было сделать три разных

int correctKey = 0;
int maxAmount = 0;
char[] bufferArrayChar;
arrayDecodeText = Arrays.copyOf(arrayDecodeText, Math.min(arrayDecodeText.length, Constants.LIMIT_SYMBOLS_FOR_FOUND_KEY));
for (int key = 0; key < Constants.alphabet.length; key++) {
int amountConjunction = 0;
bufferArrayChar = decrypt(arrayDecodeText, key);
for (int i = 0; i < bufferArrayChar.length; i++) {
amountConjunction += isCorrectKey(bufferArrayChar, i);
}
if (amountConjunction > maxAmount) {
maxAmount = amountConjunction;
correctKey = key;
}
}
return correctKey;
}

public int isCorrectKey(char[] arrayChar, int i) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Мне кажется этот метод можно сделать приватным

int amountConjunction = 0;
if (arrayChar[i] == ' ') {
amountConjunction++;
}
if (i + 2 < arrayChar.length && arrayChar[i] == ',' && arrayChar[i + 1] == ' ' && Character.isLetter(arrayChar[i + 2])) {
amountConjunction += Constants.COEFFICIENT_EFFICIENCY;
}
if (i + 2 < arrayChar.length && arrayChar[i] == ' ' && Character.isLetter(arrayChar[i + 1]) && arrayChar[i + 2] == ' ') {
amountConjunction++;
}
if (i + 2 < arrayChar.length && arrayChar[i] == '.' && arrayChar[i + 1] == ' ' &&
Character.isLetter(arrayChar[i + 2]) && Character.isUpperCase(arrayChar[i + 2])) {
amountConjunction += Constants.COEFFICIENT_EFFICIENCY;
}
return amountConjunction;
}
}
109 changes: 109 additions & 0 deletions src/main/java/com/javarush/karpeev/console/Menu.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
package com.javarush.karpeev.console;

import com.javarush.karpeev.exceptions.FileForReadNotFoundException;
import com.javarush.karpeev.exceptions.FileForWriteNotFoundException;
import com.javarush.karpeev.fileManager.FileManager;
import com.javarush.karpeev.command.CryptText;
import com.javarush.karpeev.constants.Constants;
import com.javarush.karpeev.constants.Message;

import java.util.Scanner;

public class Menu {
private int key;
private int step = Constants.STEP_START;

Scanner input = new Scanner(System.in);

public void getMenu() {
System.out.println(Message.WELCOME);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Константы это хорошо

while (step != Constants.STEP_EXIT) {
switch (getStep()) {
case 1 -> coding();
case 2 -> decoding();
case 3 -> foundKey();
default -> System.out.println(Message.BAY);
}
}
}

private void coding() {
FileManager fileManager = new FileManager();
CryptText cryptText = new CryptText();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Лучше сделать эту переменную полем тогда её не придётся всякий раз создавать при вызове методов

getKey();
try {
char[] arrayEncrypt = cryptText.encrypt(fileManager.varyTextInArrayChar(fileManager.getPathReadeFile()), key);
fileManager.writeTextInFile(fileManager.getPathWriteFile(), arrayEncrypt, arrayEncrypt.length);
System.out.println(Message.END_CODE + Message.NEXT_STEP);
} catch (FileForReadNotFoundException e) {
System.out.println(Message.NOT_FOUND_FILE_FOR_READ + Message.NEXT_STEP);
} catch (FileForWriteNotFoundException e) {
System.out.println(Message.NOT_FOUND_FILE_FOR_WRITE + Message.NEXT_STEP);
}
}

private void decoding() {
FileManager fileManager = new FileManager();
CryptText cryptText = new CryptText();
getKey();
try {
char[] arrayForDecrypt = cryptText.decrypt(fileManager.varyTextInArrayChar(fileManager.getPathReadeFile()), key);
fileManager.writeTextInFile(fileManager.getPathWriteFile(), arrayForDecrypt, arrayForDecrypt.length);
System.out.println(Message.END_DECODE + Message.NEXT_STEP);
} catch (FileForReadNotFoundException e) {
System.out.println(Message.NOT_FOUND_FILE_FOR_READ + Message.NEXT_STEP);
} catch (FileForWriteNotFoundException e) {
System.out.println(Message.NOT_FOUND_FILE_FOR_WRITE + Message.NEXT_STEP);
}
}

private void foundKey() {
FileManager fileManager = new FileManager();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

И это тоже

CryptText cryptText = new CryptText();
try {
char[] arrayDecrypt = fileManager.varyTextInArrayChar(fileManager.getPathFoundKey());
key = cryptText.bruteForce(arrayDecrypt);
fileManager.writeTextInFile(fileManager.getPathWriteFile(), cryptText.decrypt(arrayDecrypt, key), arrayDecrypt.length);
System.out.println(Message.END_DECODE + Message.END_FOUND_KEY + key + Message.NEXT_STEP);
} catch (FileForReadNotFoundException e) {
System.out.println(Message.NOT_FOUND_FILE_FOR_READ + Message.NEXT_STEP);
} catch (FileForWriteNotFoundException e) {
System.out.println(Message.NOT_FOUND_FILE_FOR_WRITE + Message.NEXT_STEP);
}
}

private int getStep() {
while (true) {
System.out.println(Message.MENU);
try {
step = Integer.parseInt(input.nextLine());
} catch (NumberFormatException e) {
System.out.println(Message.NOT_NUMBER);
continue;
}
if (step < Constants.INTERVAL_STEP_MENU_START || step > Constants.INTERVAL_STEP_MENU_END) {
System.out.println(Message.NUMBER_NOT_IN_MENU);
} else {
break;
}
}
return step;
}

public void getKey() {
while (true) {
System.out.print(Message.INPUT_KEY + (Constants.alphabet.length - 1) + ": ");
try {
key = Integer.parseInt(input.nextLine());
} catch (NumberFormatException e) {
System.out.println(Message.NOT_NUMBER_KEY + (Constants.alphabet.length - 1) + ": ");
continue;
}
if (key < 1 || key > Constants.alphabet.length - 1) {
System.out.println(Message.FALSE_NUMBER + (Constants.alphabet.length - 1) + ": ");
} else {
break;
}
}
}
}
26 changes: 26 additions & 0 deletions src/main/java/com/javarush/karpeev/constants/Constants.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.javarush.karpeev.constants;
public class Constants {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Тут всё хорошо но не хватает приватного конструктора

public static final char[] alphabet = {
'а', 'б', 'в', 'г', 'д', 'е', 'ё', 'ж', 'з', 'и', 'й',
'к', 'л', 'м', 'н', 'о', 'п', 'р', 'с', 'т', 'у', 'ф',
'х', 'ц', 'ч', 'ш', 'щ', 'ъ', 'ы', 'ь', 'э', 'ю', 'я',
'1', '2', '3', '4', '5', '6', '7', '8', '9', '0',
'А', 'Б', 'В', 'Г', 'Д', 'Е', 'Ё', 'Ж', 'З', 'И', 'Й',
'К', 'Л', 'М', 'Н', 'О', 'П', 'Р', 'С', 'Т', 'У', 'Ф',
'Х', 'Ц', 'Ч', 'Ш', 'Щ', 'Ъ', 'Ы', 'Ь', 'Э', 'Ю', 'Я',
'~', '!', '@', '#', '$', '№', ':', '^', '&', '?', '*', '(', ')', '{', '}', '-', '«', '»',
'_', ',', '/', '.', '…', '|', '<', '>', '+', ';', '%', '"', '`', '=', '\'', '\\', ' ', '—',
'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 int COEFFICIENT_EFFICIENCY = 10;
public static final int LIMIT_SYMBOLS_FOR_FOUND_KEY = 1000;
public static final int STEP_START = -1;
public static final int INTERVAL_STEP_MENU_START = 0;
public static final int INTERVAL_STEP_MENU_END = 3;
public static final int STEP_EXIT = 0;

}
22 changes: 22 additions & 0 deletions src/main/java/com/javarush/karpeev/constants/Message.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.javarush.karpeev.constants;

public class Message {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

То же самое. Ну и теперь все мы знаем что для этих целей полезно использовать интерфейс

public static final String NOT_NUMBER = "Вы ввели текст или нецелое число. Введите число от 0 до 3";
public static final String NOT_NUMBER_KEY = "Вы ввели текст или нецелое число. Введите целое число от 1 до ";
public static final String INPUT_PATH_READ_FILE = "Введите адрес файла с текстом для шифрования: ";
public static final String INPUT_PATH_FOR_FOUND_KEY = "Введите адрес зашифрованного текстового файла для поиска ключа: ";
public static final String INPUT_PATH_WRITE_FILE = "Введите адрес файла для записи: ";
public static final String FALSE_NUMBER = "Вы ввели число, которое не входит в диапазон от 1 до ";
public static final String NUMBER_NOT_IN_MENU = "\nЧисло не соответствует входному условию. Введите число от 0 до 3";
public static final String MENU = "1 - Шифрование\n2 - Расшифровка\n3 - Поиск ключа расшифровки\n0 - Выход";
public static final String WELCOME = "\nДобро пожаловать в шифратор!\n\nВведите действие в соответствии с пунктом в меню:";
public static final String INPUT_KEY = "Введите ключ - положительное целое число от 1 до ";
public static final String NEXT_STEP = "\nДля дальнейших действий выберите пункт в меню.\n";
public static final String END_CODE = "Шифрование выполнено!";
public static final String END_DECODE = "Расшифровка выполнена! ";
public static final String END_FOUND_KEY = "Поиск ключа выполнен! \nКорректный ключ: ";
public static final String NOT_FOUND_FILE_FOR_READ = "\nФайл для чтения текста не найден! Попробуйте ещё раз\n";
public static final String NOT_FOUND_FILE_FOR_WRITE = "\nФайл для записи не найден! Попробуйте ещё раз\n";
public static final String BAY = "До скорой встречи!";
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.javarush.karpeev.exceptions;

import java.io.IOException;

public class FileForReadNotFoundException extends IOException {
public FileForReadNotFoundException() {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

При таком дизайне в случае необходимости нельзя будет передать причину возникновения данного исключения

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.javarush.karpeev.exceptions;

import java.io.IOException;

public class FileForWriteNotFoundException extends IOException {
public FileForWriteNotFoundException() {
}
}
54 changes: 54 additions & 0 deletions src/main/java/com/javarush/karpeev/fileManager/FileManager.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.javarush.karpeev.fileManager;

import com.javarush.karpeev.exceptions.FileForReadNotFoundException;
import com.javarush.karpeev.exceptions.FileForWriteNotFoundException;
import com.javarush.karpeev.constants.Message;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Scanner;

public class FileManager {
Scanner scanner = new Scanner(System.in);

public char[] varyTextInArrayChar(String addressText) throws FileForReadNotFoundException {
StringBuilder textBuffer = new StringBuilder();
try (BufferedReader reader = new BufferedReader(new FileReader(addressText))) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Советую посмотреть на пакет с новыми методами ввода и вывода nio

while (reader.ready()) {
textBuffer.append(reader.readLine()).append('\n');
}
} catch (IOException e) {
throw new FileForReadNotFoundException();
}
textBuffer.deleteCharAt(textBuffer.length() - 1);
return textBuffer.toString().toCharArray();
}

public void writeTextInFile(String addressFileForWrite, char[] mas, int len) throws FileForWriteNotFoundException {
File file = new File(addressFileForWrite);
if (!file.exists()) {
throw new FileForWriteNotFoundException();
}
try (BufferedWriter writer = Files.newBufferedWriter(Path.of(addressFileForWrite))) {
writer.write(mas, 0, len);
} catch (IOException e) {
throw new FileForWriteNotFoundException();
}
}

public String getPathReadeFile() {
System.out.print(Message.INPUT_PATH_READ_FILE);
return scanner.nextLine();
}

public String getPathFoundKey() {
System.out.print(Message.INPUT_PATH_FOR_FOUND_KEY);
return scanner.nextLine();
}

public String getPathWriteFile() throws FileForWriteNotFoundException {
System.out.print(Message.INPUT_PATH_WRITE_FILE);
return scanner.nextLine();
}
}
10 changes: 10 additions & 0 deletions src/main/java/com/javarush/karpeev/main/Runner.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.javarush.karpeev.main;

import com.javarush.karpeev.console.Menu;

public class Runner {
public static void main(String[] args) {
Menu menu = new Menu();
menu.getMenu();
}
}