uebungen/sources/src/main/java/pr2/exceptions/ausnahmen_testen/CrypterCaesar.java

165 lines
5.3 KiB
Java

package pr2.exceptions.ausnahmen_testen;
/**
* Implementierung einer Caesar-Verschlüsselung.
* <p>
* Der Eingabetext ({@literal message}) darf nur aus den Groß-Buchstaben A-Z
* bestehen. Alle anderen Zeichen (einschließlich der Leerzeichen) führen zu
* einer entsprechenden Ausnahme.
* <p>
* Dasselbe gilt für die Entschlüsselung. Auch hier dürfen nur gültige
* Zeichen auftauchen. Andernfalls kommt es zu einer Ausnahme.
* <p>
* Der Schlüssel darf nur aus einem einzelnen Zeichen bestehen und muss
* ebenfalls aus dem Bereich A-Z stammen. Kleinbuchstaben oder andere
* Zeichen führen zu einer Ausnahme.
* <p>
* Zwischen den beiden Methoden muss bei gleichem Schlüssel {@code key}
* folgendes gelten:
* <p>
* {@code text.equals(decrypt(key, encrypt(key, text)) == true}.
*/
public class CrypterCaesar {
/**
* Gültige Zeichen für Schlüssel und Text.
*/
protected static final String ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
/**
* Verschlüsselt den gegebenen Text mit dem angegebenen Schlüssel.
*
* @param key Schlüssel, der verwendet werden soll.
* @param message Nachricht, die Verschlüsselt werden soll.
* @return verschlüsselter Text.
* @throws IllegalMessageException Wird geworfen, wenn die
* Nachricht ungültig ist.
* @throws IllegalKeyException Wird geworfen, wenn der Schlüssel
* ungültig ist.
*/
public String encrypt(String key, String message)
throws IllegalMessageException, IllegalKeyException {
checkKeyAndMessage(key, message);
int shift = key.charAt(0) - 'A' + 1;
return shift(message, shift);
}
/**
* Entschlüsselt den gegebenen Text mit dem angegebenen Schlüssel.
*
* @param key Schlüssel, der verwendet werden soll.
* @param cypherText Nachricht, die entschlüsselt werden soll.
* @return entschlüsselter Text.
* @throws IllegalMessageException Wird geworfen, wenn die
* Nachricht ungültig ist.
* @throws IllegalKeyException Wird geworfen, wenn der Schlüssel
* ungültig ist.
*/
public String decrypt(String key, String cypherText)
throws IllegalKeyException, IllegalMessageException {
checkKeyAndMessage(key, cypherText);
int shift = key.charAt(0) - 'A' + 1;
return shift(cypherText, -shift);
}
/**
* Verschiebt die Zeichen im Text um den gegebenen Faktor.
*
* @param text Nachricht
* @param shift Verschiebefaktor
* @return das Ergebnis als String
*/
private String shift(String text, int shift) {
StringBuilder result = new StringBuilder();
for (char c : text.toCharArray()) {
char newChar = (char) (c + shift);
if (newChar > 'Z') {
// Überlauf nach hinten
newChar = (char) (newChar - ('Z' - 'A' + 1));
}
else if (newChar < 'A') {
// Überlauf nach vorne
newChar = (char) (newChar + ('Z' - 'A' + 1));
}
result.append(newChar);
}
return result.toString();
}
/**
* Prüft Schlüssel und Nachricht.
*
* @param key der Schlüssel
* @param message die Nachricht
* @throws IllegalKeyException Schlüssel nicht OK
* @throws IllegalMessageException Nachricht nicht OK
*/
private void checkKeyAndMessage(String key, String message)
throws IllegalKeyException, IllegalMessageException {
if (!checkKey(key)) {
throw new IllegalKeyException(key);
}
if (!checkCharacters(message, ALPHABET)) {
throw new IllegalMessageException(key);
}
}
/**
* Testet den Schlüssel auf Korrektheit: Er muss mindestens die Länge 1
* haben und darf nur Zeichen von A-Z enthalten.
*
* @param key zu testender Schlüssel
* @return {@code true} if characters are ok, otherwise {@code false}
*/
protected boolean checkKey(String key) {
if (key.length() != 1) {
return false;
}
return checkCharacters(key, ALPHABET);
}
/**
* Checks the given input to ensure that it only contains the given
* character set and no other characters.
*
* @param inputChars the string to be checked
* @param charSet a string containing all allowed characters
* @return {@code true} if characters are ok, otherwise {@code false}
*/
protected boolean checkCharacters(char[] inputChars, String charSet) {
for (char c : inputChars) {
if (charSet.indexOf(c) == -1) {
return false;
}
}
return true;
}
/**
* Checks the given input to ensure that it only contains the given
* character set and no other characters.
*
* @param input the string to be checked
* @param charSet a string containing all allowed characters
* @return {@code true} if characters are ok, otherwise {@code false}
*/
protected boolean checkCharacters(String input, String charSet) {
return checkCharacters(input.toCharArray(), charSet);
}
}