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

import static com.javarush.goncharov.view.Menu.run;

public class EntryPoint {
public static void main(String[] args) {
run();
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.

в данном классе нет никакого смысла

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.javarush.goncharov.constants;

public class ApplicationCompletionConstants {
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.

Слишком неудобное название. Проще было бы назвать Messages

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 static final


public static final String SUCCESS = "Выполнение приложения завершилось успешно";
public static final String MESSAGE_IN =
"Введите путь к исходному файлу или нажмите Enter, чтобы воспользоваться демонстрационным файлом :\n" +
"(text/input.txt - используется для последующего шифрования)";
public static final String MESSAGE_OUT = "Введите путь к конечному файлу или нажмите Enter, чтобы воспользоваться демонстрационным файлом :\n" +
"(text/output.txt - сохраниться расшифрованный текст)";
public static final String MESSAGE_IN_ENCODED = "Введите путь к исходному файлу или нажмите Enter, чтобы воспользоваться демонстрационным файлом :\n" +
"(text/encoded.txt - используется для последующей расшифровки)";
public static final String MESSAGE_KEY_GENERATED = "Сгенерирован ключ под номером: ";
public static final String MESSAGE_KEY = "Введите ключ в целочисленном диапазоне : ";
public static final String INPUT_MODE = """
Выберете режим работы:\s
Чтобы зашифровать текстовый файл, введите - 1
Чтобы расшифровать текстовый файл, введите - 2
Чтобы расшифровать текстовый файл (подбор ключа методом перебора всех возможных вариантов), введите - 3: """;
public static final String DESCRIPTION_SERVICE = """
Добро пожаловать в сервис шифр Цезаря!
""";
public static final String MESSAGE_ERROR_ENCODE = "Операция кодирования завершилась ошибкой - ";
public static final String MESSAGE_ERROR_DECODE = "Операция декодирования завершилась ошибкой - ";
public static final String MESSAGE_REPEAT = "Некорректный режим работы. Допустимые значения : \"1\" - для шифрования, " +
"\"2\" - для расшифровки, \"3\" - bruteforce (подбор ключа методом перебора всех возможных вариантов) \"end\" - для завершения работы!";
}
10 changes: 10 additions & 0 deletions src/main/java/com/javarush/goncharov/constants/CryptoAlphabet.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.javarush.goncharov.constants;

public class CryptoAlphabet {
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 static final String lettersUpperCase = "АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ";
public static final String lettersLowerCase = "абвгдеёжзийклмнопрстуфхцчшщъыьэюя";
public static final String numbers = "0123456789";
public static final String symbols = ".,\"^-!& ";
public static final String ALPHABET = lettersUpperCase + lettersLowerCase + numbers + symbols;
public static final int ALPHABET_LENGTH = ALPHABET.length();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.javarush.goncharov.constants;

public class FunctionCodeConstants {

public static final String INPUT = "text/input.txt";
public static final String OUTPUT = "text/output.txt";
public static final String ENCODED = "text/encoded.txt";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.javarush.goncharov.exception;

public class ApplicationException extends RuntimeException{
public ApplicationException() {
}

public ApplicationException(String message) {
super(message);
}

public ApplicationException(String message, Throwable cause) {
super(message, cause);
}

public ApplicationException(Throwable cause) {
super(cause);
}
}
43 changes: 43 additions & 0 deletions src/main/java/com/javarush/goncharov/services/PathUtilsFunc.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.javarush.goncharov.services;

import static com.javarush.goncharov.constants.FunctionCodeConstants.*;
import static com.javarush.goncharov.services.UtilsFunc.*;

public class PathUtilsFunc {

public static String getInputFileEncode(String message){
System.out.println(message);
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.

в методах которые начинаются на Prefix get меньше всего ожидаешь увидеть вывод на консоль

String inputFileEncode = in.nextLine();
if (inputFileEncode.isEmpty()){
inputFileEncode = INPUT;
}
return inputFileEncode;
}

public static String getOutputFileEncode(String message){
System.out.println(message);
String outputFileEncode = in.nextLine();
if (outputFileEncode.isEmpty()){
outputFileEncode = OUTPUT;
}
return outputFileEncode;
}

public static String getInputFileDecode(String message){
System.out.println(message);
String inputFileDecode = in.nextLine();
if (inputFileDecode.isEmpty()){
inputFileDecode = OUTPUT;
}
return inputFileDecode;
}

public static String getOutputFileDecode(String message){
System.out.println(message);
String outputFileDecode = in.nextLine();
if (outputFileDecode.isEmpty()){
outputFileDecode = ENCODED;
}
return outputFileDecode;
}
}
52 changes: 52 additions & 0 deletions src/main/java/com/javarush/goncharov/services/UtilsFunc.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.javarush.goncharov.services;

import java.util.Scanner;
import java.util.concurrent.ThreadLocalRandom;

import static com.javarush.goncharov.constants.ApplicationCompletionConstants.*;
import static com.javarush.goncharov.constants.CryptoAlphabet.*;

public class UtilsFunc {

static Scanner in = new Scanner(System.in);

public static int getInputMode(String message){
String input;
while (true){
System.out.println(message);
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.

и тут тоже самое

input = in.nextLine();
if (input.equals("1") || input.equals("2") || input.equals("3")){
return Integer.parseInt(input);
} else if (input.equals("End".toLowerCase())) {
close();
} else {
System.out.println(MESSAGE_REPEAT);
}
}
}

public static void close(){
System.exit(0);
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 static int getRandomKey(){
int key = ThreadLocalRandom.current().nextInt(1, (ALPHABET_LENGTH + 1) / 2);
System.out.println(MESSAGE_KEY_GENERATED + key);
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 key;
}

public static int getShiftKey(String message){
String input;
while (true){
System.out.println(message);
input = in.nextLine();
if (input.isEmpty()){
return getRandomKey();
} else if (Integer.parseInt(input) >= 1 && Integer.parseInt(input) <= ALPHABET_LENGTH) {
return Integer.parseInt(input);
} else {
System.out.printf("Вы можете использовать числа от 1 до %d. \n", ALPHABET_LENGTH);
}
}
}
}
63 changes: 63 additions & 0 deletions src/main/java/com/javarush/goncharov/view/BruteForce.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package com.javarush.goncharov.view;

import com.javarush.goncharov.exception.ApplicationException;

import java.io.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static com.javarush.goncharov.constants.ApplicationCompletionConstants.*;
import static com.javarush.goncharov.constants.ApplicationCompletionConstants.SUCCESS;
import static com.javarush.goncharov.constants.CryptoAlphabet.ALPHABET_LENGTH;
import static com.javarush.goncharov.services.PathUtilsFunc.getInputFileDecode;
import static com.javarush.goncharov.services.PathUtilsFunc.getOutputFileDecode;

public class BruteForce{

private static final String REGEX = "^([а-яА-Я]+(\\s|,\\s|:\\s|;\\s|-\\s)){2,}";
private static final Pattern PATTERN = Pattern.compile(REGEX);
private static int key;
private static boolean find;

public static void brute(){
String inputFile = getInputFileDecode(MESSAGE_OUT);
String outputFileFile = getOutputFileDecode(MESSAGE_IN_ENCODED);

for (int i = 0; i < ALPHABET_LENGTH; i++) {
if (find){
break;
}
try (BufferedReader reader = new BufferedReader(new FileReader(inputFile));
BufferedWriter writer = new BufferedWriter(new FileWriter(outputFileFile))) {
while (reader.ready()) {
String result = bruteForce(reader.readLine(), i);
if (find) {
writer.write(result);
writer.newLine();
writer.flush();
}
}
} catch (IOException e) {
throw new ApplicationException(MESSAGE_ERROR_DECODE, e);
}
}
System.out.println(SUCCESS);
System.out.printf("Key used for decryption: %d%n", getKey());
}

private static String bruteForce(String textInput, int key) {
StringBuilder textOutput = new StringBuilder();
textOutput.delete(0, textOutput.length());
textOutput.append(Decode.encodeText(textInput, key));
Matcher matcher = PATTERN.matcher(textOutput);
if (matcher.find()) {
BruteForce.key = key;
BruteForce.find = true;
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 textOutput.toString();
}

private static int getKey() {
return key;
}
}
51 changes: 51 additions & 0 deletions src/main/java/com/javarush/goncharov/view/Decode.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.javarush.goncharov.view;

import com.javarush.goncharov.exception.ApplicationException;

import java.io.*;

import static com.javarush.goncharov.constants.ApplicationCompletionConstants.*;
import static com.javarush.goncharov.constants.CryptoAlphabet.ALPHABET;
import static com.javarush.goncharov.services.PathUtilsFunc.*;
import static com.javarush.goncharov.services.UtilsFunc.getShiftKey;

public class Decode {
public static void decode(){
int key = getShiftKey(MESSAGE_KEY);
String inputFile = getInputFileDecode(MESSAGE_OUT);
String outputFileFile = getOutputFileDecode(MESSAGE_IN_ENCODED);

try (BufferedReader reader = new BufferedReader(new FileReader(inputFile));
BufferedWriter writer = new BufferedWriter(new FileWriter(outputFileFile))){

while (reader.ready()){
writer.write(encodeText(reader.readLine(), key));
writer.newLine();
writer.flush();
}
} catch (IOException e) {
throw new ApplicationException(MESSAGE_ERROR_DECODE, e);
}
System.out.println(SUCCESS);
}

public static String encodeText(String string, int shift){
StringBuilder builder = new StringBuilder();
for (int i = 0; i < string.length(); i++) {
builder.append(symbolDecode(string.charAt(i), shift));
}
return builder.toString();
}

private static char symbolDecode(char symbol, int shift) {
if (ALPHABET.indexOf(symbol) != -1) {
if (ALPHABET.indexOf(symbol) - shift >= 0) {
return ALPHABET.charAt((ALPHABET.indexOf(symbol) - shift) % ALPHABET.length());
} else {
return ALPHABET.charAt(ALPHABET.length() + (ALPHABET.indexOf(symbol) - shift) % ALPHABET.length());
}
} else {
return symbol;
}
}
}
47 changes: 47 additions & 0 deletions src/main/java/com/javarush/goncharov/view/Encode.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.javarush.goncharov.view;

import com.javarush.goncharov.exception.ApplicationException;

import java.io.*;

import static com.javarush.goncharov.constants.ApplicationCompletionConstants.*;
import static com.javarush.goncharov.constants.CryptoAlphabet.ALPHABET;
import static com.javarush.goncharov.services.PathUtilsFunc.*;
import static com.javarush.goncharov.services.UtilsFunc.*;

public class Encode {
public static void encode(){
int key = getShiftKey(MESSAGE_KEY);
String inputFile = getInputFileEncode(MESSAGE_IN);
String outputFileFile = getOutputFileEncode(MESSAGE_OUT);

try (BufferedReader reader = new BufferedReader(new FileReader(inputFile));
BufferedWriter writer = new BufferedWriter(new FileWriter(outputFileFile))){

while (reader.ready()){
writer.write(encodeText(reader.readLine(), key));
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.

кодирование и декодирования выполняется построчно а не посимвольно, это сильно поможет потенциальному взломщику определить границы строк

writer.newLine();
writer.flush();
}
} catch (IOException e) {
throw new ApplicationException(MESSAGE_ERROR_ENCODE, e);
}
System.out.println(SUCCESS);
}

private static String encodeText(String string, int shift){
StringBuilder builder = new StringBuilder();
for (int i = 0; i < string.length(); i++) {
builder.append(symbolRightShift(string.charAt(i), shift));
}
return builder.toString();
}

private static char symbolRightShift(char symbol, int shift){
if (ALPHABET.indexOf(symbol) != -1){
return ALPHABET.charAt((ALPHABET.indexOf(symbol) + shift) % ALPHABET.length());
} else {
return symbol;
}
}
}
23 changes: 23 additions & 0 deletions src/main/java/com/javarush/goncharov/view/Menu.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.javarush.goncharov.view;

import static com.javarush.goncharov.constants.ApplicationCompletionConstants.*;
import static com.javarush.goncharov.services.UtilsFunc.getInputMode;
import static com.javarush.goncharov.view.BruteForce.brute;
import static com.javarush.goncharov.view.Decode.decode;
import static com.javarush.goncharov.view.Encode.encode;

public class Menu {
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 static void run(){
printMainMenu();
int startValue = getInputMode(INPUT_MODE);
switch (startValue){
case 1 -> encode();
case 2 -> decode();
case 3 -> brute();
}
}

private static void printMainMenu(){
System.out.println(DESCRIPTION_SERVICE);
}
}
Loading