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

// CaesarCipher.java

public class CaesarCipher implements Cipher {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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


private final char[] LETTERS_LOWER = CYRILLIC.toCharArray();
private final char[] LETTERS_UPPER = CYRILLIC_UPPER.toCharArray();
private final char[] SYMBOLS = SYMBOLS_STRING.toCharArray();

@Override
public String encrypt(String text, int key) {
return shiftText(text, key);
}

@Override
public String decrypt(String text, int key) {
return shiftText(text, -key);
}

private String shiftText(String text, int shift) {
StringBuilder result = new StringBuilder();

int lettersLength = LETTERS_LOWER.length;
int symbolsLength = SYMBOLS.length;

for (char c : text.toCharArray()) {
if (isCyrillicLower(c)) {
int index = indexOfChar(LETTERS_LOWER, c);
int shiftedIndex = mod(index + shift, lettersLength);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Тут какая-то странная логика если алфавит оформить в виде карты то это большое разветвления превратится в одну строчку

result.append(LETTERS_LOWER[shiftedIndex]);

} else if (isCyrillicUpper(c)) {
int index = indexOfChar(LETTERS_UPPER, c);
int shiftedIndex = mod(index + shift, lettersLength);
result.append(LETTERS_UPPER[shiftedIndex]);

} else if (isSymbol(c)) {
int index = indexOfChar(SYMBOLS, c);
int shiftedIndex = mod(index + shift, symbolsLength);
result.append(SYMBOLS[shiftedIndex]);

} else {
// Для всех остальных — копируем без изменений
result.append(c);
}
}
return result.toString();
}

private boolean isCyrillicLower(char c) {
for (char ch : LETTERS_LOWER) if (ch == c) return true;
return false;
}

private boolean isCyrillicUpper(char c) {
for (char ch : LETTERS_UPPER) if (ch == c) return true;
return false;
}

private boolean isSymbol(char c) {
for (char ch : SYMBOLS) if (ch == c) return true;
return false;
}

private int mod(int a, int b) {
int res = a % b;
if (res < 0) res += b;
return res;
}

private int indexOfChar(char[] arr, char c) {
for (int i = 0; i < arr.length; i++) {
if (arr[i] == c) return i;
}
return -1;
}
}

18 changes: 18 additions & 0 deletions src/main/java/com/javarush/ushanov/Cipher.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.javarush.ushanov;

// Cipher.java
import java.util.Locale;

public interface Cipher {
String CYRILLIC = "абвгдежзийклмнопрстуфхцчшщъыьэюя";
String CYRILLIC_UPPER = CYRILLIC.toUpperCase(Locale.forLanguageTag("ru"));
String SYMBOLS_STRING = " .,!\n?-:\\'\"";

String encrypt(String text, int key);
String decrypt(String text, int key);

default int getAlphabetLength() {
return CYRILLIC.length();
}
}

27 changes: 27 additions & 0 deletions src/main/java/com/javarush/ushanov/FileManager.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.javarush.ushanov;

// FileManager.java
import java.io.*;
import java.nio.charset.StandardCharsets;

public class FileManager {

public String readFile(String filePath) throws IOException {
StringBuilder content = new StringBuilder();
try (BufferedReader br = new BufferedReader(
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Советую обратить внимание на новые способы обращения к файловой системе

new InputStreamReader(new FileInputStream(filePath), StandardCharsets.UTF_8))) {
String line;
while ((line = br.readLine()) != null) {
content.append(line).append('\n');
}
}
return content.toString();
}

public void writeFile(String content, String filePath) throws IOException {
try (BufferedWriter bw = new BufferedWriter(
new OutputStreamWriter(new FileOutputStream(filePath), StandardCharsets.UTF_8))) {
bw.write(content);
}
}
}
117 changes: 117 additions & 0 deletions src/main/java/com/javarush/ushanov/MainApp.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package com.javarush.ushanov;

// MainApp.java
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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

import java.io.File;
import java.util.Scanner;

public class MainApp {
private static final String DEFAULT_TEXT_FOLDER = "text";

public static void main(String[] args) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Независимо от местоположения длина метода не может превышать 25 строк. Метод не должен требовать с скроллинга

Scanner scanner = new Scanner(System.in);
Cipher cipher = new CaesarCipher();
FileManager fileManager = new FileManager();
Validator validator = new Validator();

System.out.println("Select mode:");
System.out.println("1 - Encode");
System.out.println("2 - Decode");
System.out.println("0 - Exit");

int mode;
try {
mode = Integer.parseInt(scanner.nextLine().trim());
} catch (NumberFormatException e) {
System.out.println("Error: Incorrect number entered");
return;
}

if (mode == 0) {
System.out.println("Exit");
return;
}

String defaultInputFile;
String defaultOutputFile;

if (mode == 1) {
defaultInputFile = "text.txt";
defaultOutputFile = "encrypted.txt";
} else if (mode == 2) {
defaultInputFile = "encrypted.txt";
defaultOutputFile = "decrypted.txt";
} else {
System.out.println("Incorrect mode!");
return;
}

System.out.printf("Enter source (full path OR only filename OR Enter for %s): ", defaultInputFile);
String inputPath = scanner.nextLine().trim();
inputPath = resolveFilePath(inputPath, defaultInputFile);

if (!validator.isFileExists(inputPath)) {
System.out.println("Input file not found! Path: " + inputPath);
return;
}

int alphabetLength = cipher.getAlphabetLength();
System.out.printf("Enter key (non-negative integer, less than %d. Enter for 1): ", alphabetLength);

String keyInput = scanner.nextLine().trim();
int key;
if (keyInput.isEmpty()) {
key = 1; // default key
} else {
try {
key = Integer.parseInt(keyInput);
} catch (NumberFormatException e) {
System.out.println("Error: Not a number");
return;
}
}

if (!validator.isValidKey(key, cipher)) {
System.out.println("Invalid key!");
return;
}

System.out.printf("Enter destination (full path OR only filename OR Enter for %s): ", defaultOutputFile);
String outputPath = scanner.nextLine().trim();
outputPath = resolveFilePath(outputPath, defaultOutputFile);

try {
String content = fileManager.readFile(inputPath);
String processed;

if (mode == 1) {
processed = cipher.encrypt(content, key);
} else {
processed = cipher.decrypt(content, key);
}

fileManager.writeFile(processed, outputPath);
System.out.println("Done! Result in: " + outputPath);

} catch (Exception e) {
System.out.println("File processing error: " + e.getMessage());
e.printStackTrace();
}
}

private static String resolveFilePath(String input, String defaultFile) {
if (input.isEmpty()) {
return defaultFileWithTextFolder(defaultFile);
}
File file = new File(input);
if (file.isAbsolute()) {
return input;
} else {
return defaultFileWithTextFolder(input);
}
}

private static String defaultFileWithTextFolder(String filename) {
String projectDir = System.getProperty("user.dir");
return projectDir + File.separator + DEFAULT_TEXT_FOLDER + File.separator + filename;
}
}
20 changes: 20 additions & 0 deletions src/main/java/com/javarush/ushanov/Validator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.javarush.ushanov;

// Validator.java
import java.io.File;

public class Validator {

public boolean isFileExists(String filePath) {
File file = new File(filePath);
return file.exists() && file.isFile();
}

public boolean isValidKey(int key, Cipher cipher) {
int length = cipher.getAlphabetLength();
return key >= 0 && key < length;
}
}