diff --git a/.idea/misc.xml b/.idea/misc.xml index a165cb3..cbb200f 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/src/crypto/Crypto.java b/src/crypto/Crypto.java index 51d57b7..e3c4a44 100644 --- a/src/crypto/Crypto.java +++ b/src/crypto/Crypto.java @@ -1,10 +1,150 @@ package crypto; +import crypto.algorithms.CaesarAlgorithm; +import crypto.algorithms.CryptoAlgorithm; +import crypto.algorithms.MorseAlgorithm; +import crypto.algorithms.VigenereAlgorithm; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileWriter; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.sql.SQLOutput; +import java.util.Arrays; +import java.util.List; import java.util.Scanner; public class Crypto { + private CryptoAlgorithm algorithm; + private static List argsList; public static void main(String[] args) { + final String MODE = "-mode"; + final String KEY= "-key"; + final String DATA= "-data"; + final String IN = "-in"; + final String OUT = "-out"; + final String ALG = "-alg"; + Scanner scanner = new Scanner(System.in); - // write your code here + + String target = "enc"; + String message = null; + String processed = null; + String chiperKey; + String alg = "caesar"; + int index = -1; + String value; + argsList = Arrays.asList(args); + + /*Algorithm*/ + value = findArgValue(ALG); + alg = (value != null) ? value: alg; + final Crypto app = new Crypto(alg); + + /*Mode*/ + value = findArgValue(MODE); + if(value != null){ + target = value; + } + + /*Input*/ + value = findArgValue(IN); + if(value != null){ + try { + message = readFromFile(value); + } catch (IOException e) { + e.printStackTrace(); + System.exit(0); + } + } else{ + value = findArgValue(DATA); + if(value != null){ + message = value; + } else{ + System.out.println("Enter data:"); + message = scanner.nextLine(); + } + } + + /*Key*/ + value = findArgValue(KEY); + if(value != null){ + chiperKey = value; + } else{ + System.out.println("Enter key:"); + chiperKey = scanner.nextLine(); + + } + + /*Get message*/ + if(target.equals("dec")){ + processed = app.dec(message, chiperKey); + } else{ + processed = app.enc(message, chiperKey); + } + + /*Output*/ + value = findArgValue(OUT); + if(value != null){ + try { + writeToFile(value, processed); + } catch (IOException e) { + e.printStackTrace(); + System.exit(0); + } + } else{ + System.out.println(processed); + } } + public static String findArgValue(String key){ + int index = argsList.indexOf(key); + if(index != -1){ + return argsList.get(index+1); + } + return null; + } + + public Crypto(String alg) { + switch (alg) { + case "caesar": + this.algorithm = new CaesarAlgorithm(); + break; + case "morse": + this.algorithm = new MorseAlgorithm(); + break; + case "vigenere": + this.algorithm = new VigenereAlgorithm(); + break; + default: + this.algorithm = new CaesarAlgorithm(); + } + } + private String enc(String data, String key){ + return algorithm.enc(data, key); + } + private String dec(String data, String key){ + return algorithm.dec(data, key); + } + private static String readFromFile(String filename) throws IOException { + try { + return new String(Files.readAllBytes(Paths.get(filename))); + } catch (IOException e) { + System.out.println("Not found file " + filename); + throw e; + } + } + private static void writeToFile(String filename, String data) throws IOException { + File outputFile = new File(filename); + try (FileWriter writer = new FileWriter(outputFile)) { + writer.write(data); + System.out.println("Success! Write to: " + outputFile.getName()); + } catch (IOException e) { + System.out.println("Cannot write output message to file"); + throw e; + } + } + + } diff --git a/src/crypto/algorithms/CaesarAlgorithm.java b/src/crypto/algorithms/CaesarAlgorithm.java new file mode 100644 index 0000000..9a095b9 --- /dev/null +++ b/src/crypto/algorithms/CaesarAlgorithm.java @@ -0,0 +1,28 @@ +package crypto.algorithms; + +public class CaesarAlgorithm implements CryptoAlgorithm { + @Override + public String enc(String originalStr, String key){ + int offset = Integer.parseInt(key); + return offsetAll(originalStr, offset); + } + + @Override + public String dec(String originalStr, String key){ + int offset = Integer.parseInt(key); + return offsetAll(originalStr, -offset); + } + + private String offsetAll(String originalStr, int offset){ + StringBuilder out = new StringBuilder(); + char[] letters = new char[originalStr.length()]; + originalStr.getChars(0, originalStr.length(), letters, 0 ); + + for (int letter : letters){ + letter = (letter + offset); + out.append((char)letter); + } + + return out.toString(); + } +} diff --git a/src/crypto/algorithms/CryptoAlgorithm.java b/src/crypto/algorithms/CryptoAlgorithm.java new file mode 100644 index 0000000..5c8ec4c --- /dev/null +++ b/src/crypto/algorithms/CryptoAlgorithm.java @@ -0,0 +1,8 @@ +package crypto.algorithms; + +import java.util.Optional; + +public interface CryptoAlgorithm { + String enc(String offset, String key); + String dec(String offset, String key); +} diff --git a/src/crypto/algorithms/MorseAlgorithm.java b/src/crypto/algorithms/MorseAlgorithm.java new file mode 100644 index 0000000..286364f --- /dev/null +++ b/src/crypto/algorithms/MorseAlgorithm.java @@ -0,0 +1,59 @@ +package crypto.algorithms; + +public class MorseAlgorithm implements CryptoAlgorithm { + /*available punctuation*/ + private static final String PUNCTUATIONS = ".,!?"; + + @Override + public String enc(String message, String key) { + StringBuilder out = new StringBuilder(); + char[] letters = new char[message.length()]; + message.getChars(0, message.length(), letters, 0 ); + + MorseAlphabet morseCode; + String strLetter; + for (char letter : letters){ + strLetter = Character.toString(letter); + if(Character.isLetter(letter)){ + morseCode = MorseAlphabet.valueOf(strLetter.toUpperCase()); + out.append(morseCode.toString()); + } else if(Character.isDigit(letter)) { + morseCode = MorseAlphabet.NUMBER; + out.append(morseCode.toString(strLetter)); + }else if(MorseAlgorithm.PUNCTUATIONS.contains(Character.toString(letter))){ + morseCode = MorseAlphabet.PUNCTUATION; + out.append(morseCode.toString(strLetter)); + }else{ + out.append(letter); + } + if(letter == ' '){ + out.append(" "); + } else{ + out.append(' '); + } + + } + return out.toString(); + } + + @Override + public String dec(String message, String key) { + StringBuffer out = new StringBuffer(); + MorseAlphabet[] alphabet = MorseAlphabet.values(); + String[] words = message.split(" "); + String[] letters; + String morseCode; + for (int i = 0; i < words.length; i++){ + letters = words[i].split(" "); + for (int j=0;j< letters.length;j++){ + morseCode = letters[j]; + out.append(MorseAlphabet.getValue(morseCode)); + } + if(i != words.length - 1){ + out.append(' '); + } + } + return out.toString(); + } + +} diff --git a/src/crypto/algorithms/MorseAlphabet.java b/src/crypto/algorithms/MorseAlphabet.java new file mode 100644 index 0000000..6e28c09 --- /dev/null +++ b/src/crypto/algorithms/MorseAlphabet.java @@ -0,0 +1,216 @@ +package crypto.algorithms; + +public enum MorseAlphabet { +// static MorseAlphabet va + A { + @Override + public String toString() { + return ".-"; + } + }, + B { + @Override + public String toString() { + return "-..."; + } + }, + C { + @Override + public String toString() { + return "-.-."; + } + }, + D { + @Override + public String toString() { + return "−.."; + } + }, + E { + @Override + public String toString() { + return "."; + } + }, + F { + @Override + public String toString() { + return "..-."; + } + }, + G { + @Override + public String toString() { + return "--."; + } + }, + H { + @Override + public String toString() { + return "...."; + } + }, + I { + @Override + public String toString() { + return ".."; + } + }, + J { + @Override + public String toString() { + return ".---"; + } + }, + K { + @Override + public String toString() { + return "-.-"; + } + }, + L { + @Override + public String toString() { + return ".-.."; + } + }, + M { + @Override + public String toString() { + return "--"; + } + }, + N { + @Override + public String toString() { + return "-."; + } + }, + O { + @Override + public String toString() { + return "---"; + } + }, + P { + @Override + public String toString() { + return ".--."; + } + }, + Q { + @Override + public String toString() { + return "--.-"; + } + }, + R { + @Override + public String toString() { + return ".-."; + } + }, + S { + @Override + public String toString() { + return "..."; + } + }, + T { + @Override + public String toString() { + return "-"; + } + }, + U { + @Override + public String toString() { + return "..-"; + } + }, + V { + @Override + public String toString() { + return "...-"; + } + }, + W { + @Override + public String toString() { + return ".--"; + } + }, + X { + @Override + public String toString() { + return "-..-"; + } + }, + Y { + @Override + public String toString() { + return "-.--"; + } + }, + Z { + @Override + public String toString() { + return "--.."; + } + }, + NUMBER{ + public String toString(String num) { + return new String[]{ + "−−−−−", + ".−−−−", + "..---", + "...--", + "....-", + ".....", + "-....", + "--...", + "---..", + "----.", + "-----", + }[Integer.parseInt(num)]; + } + }, + PUNCTUATION{ + public String toString(String punct) { + switch (punct){ + case ".": return ".-.-.-"; + case ",": return "--..--"; + case "?": return "..--.."; + case "!": return "-.-.--"; + default: return ""; + } + } + }; + String toString(String num){ + return toString(); + } + static String getValue(String code){ + MorseAlphabet[] alphabet = MorseAlphabet.values(); + for(int i=0; i < alphabet.length; i++){ + if(alphabet[i] == MorseAlphabet.NUMBER){ + for(int j = 0; j < 10; j++){ + if(MorseAlphabet.NUMBER.toString(Integer.toString(j)).equals(code)){ + return Integer.toString(j); + } + } + } else if(alphabet[i] == MorseAlphabet.PUNCTUATION) { + switch (code){ + case ".-.-.-": return "."; + case "--..--": return ","; + case "..--..": return "?"; + case "-.-.--": return "!"; + default: return ""; + } + + }else if(alphabet[i].toString().equals(code)){ + return alphabet[i].name(); + } + } + return null; + } +} diff --git a/src/crypto/algorithms/VigenereAlgorithm.java b/src/crypto/algorithms/VigenereAlgorithm.java new file mode 100644 index 0000000..ec201bc --- /dev/null +++ b/src/crypto/algorithms/VigenereAlgorithm.java @@ -0,0 +1,41 @@ +package crypto.algorithms; + +public class VigenereAlgorithm implements CryptoAlgorithm{ + @Override + public String enc(String message, String key) { + message = message.toUpperCase(); + key = key.toUpperCase(); + StringBuilder out = new StringBuilder(); + message = message.toUpperCase(); + for (int i = 0, j = 0; i < message.length(); i++) + { + char c = message.charAt(i); + if (c < 'A' || c > 'Z'){ + out.append(c); + }else{ + out.append((char) ((c + key.charAt(j) - 2 * 'A') % 26 + 'A')); + j = ++j % key.length(); + } + } + return out.toString(); + } + + @Override + public String dec(String message, String key) { + message = message.toUpperCase(); + key = key.toUpperCase(); + StringBuilder out = new StringBuilder(); + message = message.toUpperCase(); + for (int i = 0, j = 0; i < message.length(); i++) + { + char c = message.charAt(i); + if (c < 'A' || c > 'Z'){ + out.append(c); + }else{ + out.append((char) ((c - key.charAt(j) + 26) % 26 + 'A')); + j = ++j % key.length(); + } + } + return out.toString(); + } +}