-
Notifications
You must be signed in to change notification settings - Fork 47
Ushanov: 2 tasks complete #34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| 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 { | ||
|
|
||
| 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); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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; | ||
| } | ||
| } | ||
|
|
||
| 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(); | ||
| } | ||
| } | ||
|
|
| 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( | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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); | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,117 @@ | ||
| package com.javarush.ushanov; | ||
|
|
||
| // MainApp.java | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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; | ||
| } | ||
| } | ||
| 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; | ||
| } | ||
| } | ||
|
|
||
|
|
||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Приложение лучше разбить на пакеты даже если классов мало