From 9886f9f45edc7b7965448aec5be410eca2f7f70d Mon Sep 17 00:00:00 2001 From: lemarginal Date: Sun, 7 Sep 2025 03:08:27 +0300 Subject: [PATCH] CryptoAnalyzerPantera --- .../com/javarush/ushanov/CaesarCipher.java | 79 ++++++++++++ .../java/com/javarush/ushanov/Cipher.java | 18 +++ .../com/javarush/ushanov/FileManager.java | 27 ++++ .../java/com/javarush/ushanov/MainApp.java | 117 ++++++++++++++++++ .../java/com/javarush/ushanov/Validator.java | 20 +++ 5 files changed, 261 insertions(+) create mode 100644 src/main/java/com/javarush/ushanov/CaesarCipher.java create mode 100644 src/main/java/com/javarush/ushanov/Cipher.java create mode 100644 src/main/java/com/javarush/ushanov/FileManager.java create mode 100644 src/main/java/com/javarush/ushanov/MainApp.java create mode 100644 src/main/java/com/javarush/ushanov/Validator.java diff --git a/src/main/java/com/javarush/ushanov/CaesarCipher.java b/src/main/java/com/javarush/ushanov/CaesarCipher.java new file mode 100644 index 0000000..ea725a6 --- /dev/null +++ b/src/main/java/com/javarush/ushanov/CaesarCipher.java @@ -0,0 +1,79 @@ +package com.javarush.ushanov; + +// CaesarCipher.java + +public class CaesarCipher implements Cipher { + + 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); + 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; + } +} + diff --git a/src/main/java/com/javarush/ushanov/Cipher.java b/src/main/java/com/javarush/ushanov/Cipher.java new file mode 100644 index 0000000..dfd64f9 --- /dev/null +++ b/src/main/java/com/javarush/ushanov/Cipher.java @@ -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(); + } +} + diff --git a/src/main/java/com/javarush/ushanov/FileManager.java b/src/main/java/com/javarush/ushanov/FileManager.java new file mode 100644 index 0000000..af69ff0 --- /dev/null +++ b/src/main/java/com/javarush/ushanov/FileManager.java @@ -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( + 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); + } + } +} diff --git a/src/main/java/com/javarush/ushanov/MainApp.java b/src/main/java/com/javarush/ushanov/MainApp.java new file mode 100644 index 0000000..c7735b9 --- /dev/null +++ b/src/main/java/com/javarush/ushanov/MainApp.java @@ -0,0 +1,117 @@ +package com.javarush.ushanov; + +// MainApp.java +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) { + 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; + } +} diff --git a/src/main/java/com/javarush/ushanov/Validator.java b/src/main/java/com/javarush/ushanov/Validator.java new file mode 100644 index 0000000..88fde0e --- /dev/null +++ b/src/main/java/com/javarush/ushanov/Validator.java @@ -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; + } +} + + +