This commit is contained in:
Daniel
2024-11-14 22:41:05 +02:00
parent da0a250670
commit 4871de2413
7 changed files with 426 additions and 11 deletions

7
.idea/misc.xml generated
View File

@@ -1,6 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="openjdk-23" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>

View File

@@ -8,10 +8,17 @@
<artifactId>Cypher</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>com.github.freva</groupId>
<artifactId>ascii-table</artifactId>
<version>1.2.0</version>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>23</maven.compiler.source>
<maven.compiler.target>23</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>

View File

@@ -1,4 +1,19 @@
package org.lumijiez;
public class DoubleCaesar {
public static String encode(int key, String keyWord, String content) {
StringBuilder encoded = new StringBuilder();
String fixedContent = content.replaceAll("\\s","");
Utils.ALPHABET = Utils.getDoubleCaesarAlphabet(Utils.toCaesarKey(keyWord));
for (char ch : fixedContent.toCharArray()) {
encoded.append(Utils.toNthLetter((Utils.getPos(ch) + key) % Utils.ALPHABET.length()));
}
Utils.returnAlphabet();
return encoded.toString();
}
}

View File

@@ -1,17 +1,86 @@
package org.lumijiez;
//TIP To <b>Run</b> code, press <shortcut actionId="Run"/> or
// click the <icon src="AllIcons.Actions.Execute"/> icon in the gutter.
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
//TIP Press <shortcut actionId="ShowIntentionActions"/> with your caret at the highlighted text
// to see how IntelliJ IDEA suggests fixing it.
System.out.printf("Hello and welcome!");
Scanner scanner = new Scanner(System.in);
boolean exit = false;
for (int i = 1; i <= 5; i++) {
//TIP Press <shortcut actionId="Debug"/> to start debugging your code. We have set one <icon src="AllIcons.Debugger.Db_set_breakpoint"/> breakpoint
// for you, but you can always add more by pressing <shortcut actionId="ToggleLineBreakpoint"/>.
System.out.println("i = " + i);
while (!exit) {
System.out.println("Choose an option:");
System.out.println("1. Simple Caesar Cipher");
System.out.println("2. Double Caesar Cipher");
System.out.println("3. Exit");
int choice = scanner.nextInt();
scanner.nextLine();
switch (choice) {
case 1:
System.out.println("Simple Caesar Cipher");
System.out.println("1. Encode");
System.out.println("2. Decode");
System.out.print("Select option: ");
int simpleChoice = scanner.nextInt();
System.out.print("Enter the key (an integer): ");
int simpleKey = scanner.nextInt();
scanner.nextLine();
System.out.print("Enter the content: ");
String simpleContent = scanner.nextLine();
if (simpleKey <= 0) {
System.out.println("Invalid key. Please enter a positive integer.");
break;
}
if (simpleChoice == 1) {
String encodedSimple = SimpleCaesar.encode(simpleKey, simpleContent);
System.out.println("Encoded: " + encodedSimple);
} else if (simpleChoice == 2) {
String decodedSimple = SimpleCaesar.decode(simpleKey, simpleContent);
System.out.println("Decoded: " + decodedSimple);
} else {
System.out.println("Invalid option.");
}
break;
case 2:
System.out.println("Double Caesar Cipher");
System.out.print("Enter the key (an integer): ");
int doubleKey = scanner.nextInt();
scanner.nextLine();
System.out.print("Enter the keyword (more than 7 letters A-Z): ");
String doubleKeyWord = scanner.nextLine();
if (!isValidKeyword(doubleKeyWord)) {
System.out.println("Invalid keyword. Please ensure it is longer than 7 characters and contains only letters A-Z.");
break;
}
System.out.print("Enter the content: ");
String doubleContent = scanner.nextLine();
String encodedDouble = DoubleCaesar.encode(doubleKey, doubleKeyWord, doubleContent);
System.out.println("Encoded: " + encodedDouble);
break;
case 3:
exit = true;
System.out.println("Exiting...");
break;
default:
System.out.println("Invalid option. Please choose again.");
}
System.out.println("================");
}
scanner.close();
}
}
private static boolean isValidKeyword(String keyword) {
return keyword.length() > 7 && keyword.matches("[A-Z]+");
}
}

View File

@@ -1,4 +1,33 @@
package org.lumijiez;
public class SimpleCaesar {
public static String encode(int key, String content) {
StringBuilder encoded = new StringBuilder();
String fixedContent = content.replaceAll("\\s","");
for (char ch : fixedContent.toCharArray()) {
encoded.append(Utils.toNthLetter((Utils.getPos(ch) + key) % Utils.ALPHABET.length()));
}
return encoded.toString();
}
public static String decode(int key, String content) {
StringBuilder decoded = new StringBuilder();
for (char ch : content.toCharArray()) {
int currentPosition = Utils.getPos(ch);
int newPosition = (currentPosition - key) % Utils.ALPHABET.length();
if (newPosition < 0) {
newPosition += Utils.ALPHABET.length();
}
decoded.append(Utils.toNthLetter(newPosition));
}
return decoded.toString();
}
}

View File

@@ -0,0 +1,64 @@
package org.lumijiez;
import java.util.LinkedHashSet;
public class Utils {
//public static String ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ";
public static String ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
public static void returnAlphabet() {
Utils.ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
//Utils.ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ";
}
public static String toCaesarKey(String key) {
LinkedHashSet<Character> linkedHashSet = new LinkedHashSet<>();
key.chars().forEach(ch -> linkedHashSet.add((char) ch));
StringBuilder caesarKey = new StringBuilder();
linkedHashSet.forEach(caesarKey::append);
return caesarKey.toString().toUpperCase();
}
public static char toNthLetter(int n) {
if (n >= ALPHABET.length()) {
throw new IllegalArgumentException("n must be between 1 and " + (ALPHABET.length() - 1));
}
if (!ALPHABET.contains(String.valueOf(ALPHABET.charAt(n)))) {
throw new IllegalArgumentException("Please only use letter from this alphabet " + Utils.ALPHABET);
}
return ALPHABET.charAt(n);
}
public static int getPos(char letter) {
int index = ALPHABET.indexOf(letter);
if (index == -1) {
throw new IllegalArgumentException("Input must be a character in the alphabet: " + ALPHABET);
}
return index;
}
public static String getDoubleCaesarAlphabet(String key) {
LinkedHashSet<Character> linkedHashSet = new LinkedHashSet<>();
for (char c : key.toCharArray()) {
linkedHashSet.add(c);
}
for (char ch : ALPHABET.toCharArray()) {
linkedHashSet.add(ch);
}
StringBuilder newAlphabet = new StringBuilder();
for (char ch : linkedHashSet) {
newAlphabet.append(ch);
}
return newAlphabet.toString();
}
}

View File

@@ -0,0 +1,224 @@
package org.lumijiez;
import com.github.freva.asciitable.AsciiTable;
import com.github.freva.asciitable.Column;
import java.util.Scanner;
public class Vigenere {
private static final int ALPHABET_SIZE = 31;
private static final String ROMANIAN_ALPHABET = "AĂÂBCDEFGHIÎJKLMNOPQRSȘTȚUVWXYZ";
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
boolean continueProgram = true;
while (continueProgram) {
printMenu();
int choice = getValidChoice(scanner);
switch (choice) {
case 1:
performEncryption(scanner);
break;
case 2:
performDecryption(scanner);
break;
case 3:
printTabulaRecta();
break;
case 4:
continueProgram = false;
System.out.println("Program încheiat. La revedere!");
break;
default:
System.out.println("Opțiune invalidă!");
}
}
scanner.close();
}
private static void printMenu() {
System.out.println("\n=== Cifrul Vigenère pentru Limba Română ===");
System.out.println("1. Criptare");
System.out.println("2. Decriptare");
System.out.println("3. Afișare Tabula Recta");
System.out.println("4. Ieșire");
System.out.print("Alegeți opțiunea (1-4): ");
}
private static void printTabulaRecta() {
System.out.println("\n=== Tabula Recta pentru Alfabetul Românesc ===\n");
String[] headers = new String[ALPHABET_SIZE + 1];
headers[0] = "K\\M";
for (int i = 0; i < ALPHABET_SIZE; i++) {
headers[i + 1] = String.valueOf(ROMANIAN_ALPHABET.charAt(i));
}
String[][] data = new String[ALPHABET_SIZE][ALPHABET_SIZE + 1];
for (int i = 0; i < ALPHABET_SIZE; i++) {
data[i][0] = String.valueOf(ROMANIAN_ALPHABET.charAt(i));
for (int j = 0; j < ALPHABET_SIZE; j++) {
int encryptedIndex = (i + j) % ALPHABET_SIZE;
data[i][j + 1] = String.valueOf(ROMANIAN_ALPHABET.charAt(encryptedIndex));
}
}
Column[] columns = new Column[ALPHABET_SIZE + 1];
columns[0] = new Column()
.header(headers[0])
.with(row -> ((String[])row)[0]);
for (int i = 1; i <= ALPHABET_SIZE; i++) {
final int colIndex = i;
columns[i] = new Column()
.header(headers[i])
.with(row -> ((String[])row)[colIndex]);
}
System.out.println(AsciiTable.getTable(AsciiTable.FANCY_ASCII, columns, data));
System.out.println("\nInstrucțiuni de utilizare:");
System.out.println("1. K\\M: K = litera din cheie, M = litera din mesaj");
System.out.println("2. Pentru a cripta, găsiți litera din mesaj (M) în prima linie");
System.out.println("3. Găsiți litera din cheie (K) în prima coloană");
System.out.println("4. Intersecția liniei K cu coloana M este litera criptată");
}
private static int getValidChoice(Scanner scanner) {
while (!scanner.hasNextInt()) {
System.out.println("Vă rugăm introduceți un număr!");
scanner.next();
}
return scanner.nextInt();
}
private static void performEncryption(Scanner scanner) {
scanner.nextLine();
String key = getValidKey(scanner);
System.out.print("Introduceți mesajul de criptat: ");
String message = getValidMessage(scanner);
String encryptedText = encrypt(message, key);
System.out.println("\nTextul criptat: " + encryptedText);
System.out.println("\nInformații despre procesul de criptare:");
System.out.println("Lungimea cheii: " + key.length());
System.out.println("Lungimea mesajului original: " + message.length());
System.out.println("Lungimea mesajului criptat: " + encryptedText.length());
}
private static void performDecryption(Scanner scanner) {
scanner.nextLine();
String key = getValidKey(scanner);
System.out.print("Introduceți textul criptat: ");
String encryptedMessage = getValidMessage(scanner);
String decryptedText = decrypt(encryptedMessage, key);
System.out.println("\nTextul decriptat: " + decryptedText);
System.out.println("\nInformații despre procesul de decriptare:");
System.out.println("Lungimea cheii: " + key.length());
System.out.println("Lungimea textului criptat: " + encryptedMessage.length());
System.out.println("Lungimea textului decriptat: " + decryptedText.length());
}
private static String getValidKey(Scanner scanner) {
String key;
do {
System.out.print("Introduceți cheia (minim 7 caractere): ");
key = preprocessText(scanner.nextLine());
if (key.length() < 7) {
System.out.println("Eroare: Cheia trebuie să aibă cel puțin 7 caractere!");
continue;
}
if (isValidRomanianText(key)) {
System.out.println("Eroare: Cheia poate conține doar litere românești!");
continue;
}
break;
} while (true);
return key;
}
private static String getValidMessage(Scanner scanner) {
String message;
do {
message = preprocessText(scanner.nextLine());
if (message.isEmpty()) {
System.out.println("Eroare: Mesajul nu poate fi gol!");
System.out.print("Introduceți din nou: ");
continue;
}
if (isValidRomanianText(message)) {
System.out.println("Eroare: Mesajul poate conține doar litere românești!");
System.out.print("Introduceți din nou: ");
continue;
}
break;
} while (true);
return message;
}
private static String preprocessText(String text) {
return text.replaceAll("\\s+", "").toUpperCase();
}
private static boolean isValidRomanianText(String text) {
for (char c : text.toCharArray()) {
if (ROMANIAN_ALPHABET.indexOf(c) == -1) {
return true;
}
}
return false;
}
private static String encrypt(String message, String key) {
StringBuilder encryptedText = new StringBuilder();
int keyLength = key.length();
for (int i = 0; i < message.length(); i++) {
char messageChar = message.charAt(i);
char keyChar = key.charAt(i % keyLength);
int messageIndex = ROMANIAN_ALPHABET.indexOf(messageChar);
int keyIndex = ROMANIAN_ALPHABET.indexOf(keyChar);
int encryptedIndex = (messageIndex + keyIndex) % ALPHABET_SIZE;
encryptedText.append(ROMANIAN_ALPHABET.charAt(encryptedIndex));
}
return encryptedText.toString();
}
private static String decrypt(String encryptedText, String key) {
StringBuilder decryptedText = new StringBuilder();
int keyLength = key.length();
for (int i = 0; i < encryptedText.length(); i++) {
char encryptedChar = encryptedText.charAt(i);
char keyChar = key.charAt(i % keyLength);
int encryptedIndex = ROMANIAN_ALPHABET.indexOf(encryptedChar);
int keyIndex = ROMANIAN_ALPHABET.indexOf(keyChar);
int decryptedIndex = (encryptedIndex - keyIndex + ALPHABET_SIZE) % ALPHABET_SIZE;
decryptedText.append(ROMANIAN_ALPHABET.charAt(decryptedIndex));
}
return decryptedText.toString();
}
}