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
66 changes: 66 additions & 0 deletions src/main/java/com/javarush/toporov/CaesarCipher.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package com.javarush.toporov;

public class CaesarCipher {
public final static char[] ALPHABET_UPPER = "АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ".toCharArray();
public final static char[] ALPHABET_LOWER = "абвгдеёзийклмнопрстуфхцчшщъыьэюя".toCharArray();

public static String encrypt(String text, int shift) {

//создание пустой строки для сохранения результата
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

комментарии лучше оформлять в формате javadoc и не по русски а english (будет один индус в команде и придется все переводить для него, так что лучше сразу на english). Но у нас можно и на русском, просто привычка плохая )


StringBuilder result = new StringBuilder();

//перебор входного текста
for (int i = 0; i < text.length(); i++) {
boolean found = false;

//берем текущий символ из строки
char currentChar = text.charAt(i);
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Тут весь текст целиком будет нужен и будет ограничение (по размеру кучи), а если бы посимвольно обрабатывать из потока в поток, то ограничений бы не было. Не так важно, но если бы это было серверное приложение то было бы очень важно - там памяти обычно сильно меньше


//поиск текущей буквы currentChar в массиве ALPHABET
for (int j = 0; j < ALPHABET_UPPER.length; j++) {

//сравниваю букву из текста с буквой из алфавита
if (currentChar == ALPHABET_UPPER[j]) {
//j- индекс буквы в алфавите, shift - на сколько нужно сдвинуть, % ALPHABET.length - что бы не выйти за границы
int newIndex = (j + shift) % ALPHABET_UPPER.length;

if (newIndex < 0) {
//добавляем в результат зашифрованную букву
newIndex += ALPHABET_UPPER.length;
}
result.append(ALPHABET_UPPER[newIndex]);
found = true;
break;
}
}
//если символ не нашёлся в алфавите, проверяем маленькие буквы
if (!found) {
for (int j = 0; j < ALPHABET_LOWER.length; j++) {
if (currentChar == ALPHABET_LOWER[j]) {
int newIndex = j + shift;
newIndex = newIndex % ALPHABET_LOWER.length;
if (newIndex < 0) {
newIndex = newIndex + ALPHABET_LOWER.length;
}
result.append(ALPHABET_LOWER[newIndex]);
found = true;
break;
}

}

}
if (!found) {
result.append(currentChar);
}
}

return result.toString();
}

public static String decrypt(String text, int shift) {
return encrypt(text, -shift);
}

}
36 changes: 36 additions & 0 deletions src/main/java/com/javarush/toporov/FileHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.javarush.toporov;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;

public class FileHandler {

// Метод для чтения содержимого файлf
public String readStringFromFile(String path) {
try {
// Чтение файла и возврат содержимого
return Files.readString(Path.of(path), StandardCharsets.UTF_8);
} catch (IOException e) {
// Ловим ошибку, если файл не найден или недоступен
System.out.println("Error reading file.");
return null;
}
}

// Метод для записи в файл
public void writeStringToFile(String inputPath, String content) {
// Получение родительской папки из пути исходного файл
Path parent = Path.of(inputPath).getParent();
// Создание пути для нового файла с именем "output.txt"
Path outputPath = parent.resolve("output.txt");
try {
Files.writeString(outputPath, content, StandardCharsets.UTF_8);
System.out.println("The result is saved in output.txt");
} catch (IOException e) {
System.out.println("An error occurred while writing to the output file.");
e.printStackTrace();
}
}
}
57 changes: 57 additions & 0 deletions src/main/java/com/javarush/toporov/MainApp.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.javarush.toporov;


import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Scanner;

public class MainApp {
public static void main(String[] args) {
UserInterface ui = new UserInterface();
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Имена лучше писать полностью: userInterface (ui - тут еще можно догадаться) fileHandler (а вот это fh - уже мало кто поймет)

FileHandler fh = new FileHandler();


String path = null;
String inputText = null;

int choice = ui.getEncryptionMethodChoice();
int shift = ui.getKey();
int mode = ui.getWorkModeChoice();

// Если пользователь выбрал работу с файлом
if (mode == 1) {
// Получение пути к файлу от пользователя
path = ui.getFilePath();
// Проверка, что путь не пустой
if (path != null) {
// Чтение текста из файла с помощью FileHandler
inputText = fh.readStringFromFile(path);
}
} else {
// Получение текста напрямую из консоли
inputText = ui.getTextFromConsole();
}


String result = "";
// Если выбран режим шифрования
if (choice == 1) {
// Шифрование текста
result = CaesarCipher.encrypt(inputText, shift);
} else if (choice == 2) {
result = CaesarCipher.decrypt(inputText, shift);
}

// Если результат нужно сохранить в файл
if (mode == 1) {
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Это магия. Что такое 1? Почему не 10 или не 100 или не 2? Нужна константа с понятным именем

// Запись результата в файл
fh.writeStringToFile(path, result);

} else {
// Вывод результата - консоль
ui.printResult(result);
}
}
}
85 changes: 85 additions & 0 deletions src/main/java/com/javarush/toporov/UserInterface.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package com.javarush.toporov;


import java.io.IOException;
import java.util.Scanner;

public class UserInterface {
Scanner scanner = new Scanner(System.in);
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

А что с модификаторами доступа? packege-private - это самый редкий вариант. Лучше явно все указать.


// Метод для получения выбора шифрования/дешифрования.
public int getEncryptionMethodChoice() {
// Бесконечный цикл, который работает до получения верного ответа
while (true) {
System.out.println("Choose an encryption, method: \n 1. Encrypt \n 2. Decrypt \n 3. BruteForce");
try {
int choice = Integer.parseInt(scanner.nextLine());
if (choice == 1 || choice == 2) {
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Константы с понятными именами, а не 1 и 2

return choice;
} else {
// если число некорректно
System.out.println("Please enter the correct value (1 or 2).");
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

И тут их тоже надо использовать. Не надо хардкодить 1 и 2

}
// Ловим ошибку, если введено не число
} catch (NumberFormatException e) {
System.out.println("Invalid input. Please enter a number.");
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Ой нет. e терять нельзя. Его или выводят или логируют. Но не "теряют" никогда.

}
}
}

// Метод для получения ключа (сдвига)
public int getKey() {
// Цикл для проверки корректности ввода ключа
while (true) {
System.out.println("Choose key:");
try {
return Integer.parseInt(scanner.nextLine());
} catch (NumberFormatException e) {
System.out.println("Invalid input. Please enter a number.");
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

то же

}
}
}

// Метод для получения выбора режима (файл/консоль)
public int getWorkModeChoice() {
// Цикл для проверки корректности ввода режима
while (true) {
System.out.println("Do you want to work with a file or a console? \n 1. File \n 2. Console");
try {
int mode = Integer.parseInt(scanner.nextLine());
if (mode == 1 || mode == 2 ) {
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

было выше

return mode;
} else {
System.out.println("Please enter the correct value (1 or 2).");
}
} catch (NumberFormatException e) {
System.out.println("Invalid input. Please enter a number.");
}
}
}

// Метод для получения пути к файлу
public String getFilePath() {
while (true) {
System.out.println("Enter the path to the file:");
String path = scanner.nextLine();
if (path != null && !path.trim().isEmpty()) {
return path;
} else {
System.out.println("Please specify a valid file path.");
}
}
}


// Метод для получения текста из консоли
public String getTextFromConsole() {
System.out.println("Enter the text:");
return scanner.nextLine();
}

// Метод для вывода результата в консоль
public void printResult(String result) {
System.out.println("The result: " + result);
}
}