Cäsar-Verschlüsselung #
Falls du noch nicht mit der Cäsar-Verschlüsselung vertraut bist, sieh’ dir zuerst die Seiten dazu auf Wikipedia an.
Aufgabe #
Ergänze die Methode verschluessele
in der Klasse Caesar
. Die Datei beinhaltet einen Test – lass ihn regelmäßig laufen und überprüfe, ob deine Implementierung funktioniert. Verwende bei Bedarf die beiden in der Klasse enthaltenen Methoden positionImAlphabet
und buchstabeAnPosition
.
class Caesar {
static String verschluessele(String text, int verschiebung) {
String verschluesselt = "";
// Hier kommt dein Code hin:
return verschluesselt;
}
/**
* Die Methode positionImAlphabet gibt für einzelne
* Buchstaben deren Position (1..26) im Alphabet zurück.
* Für Umlaute, andere Zeichen und längere Zeichenketten
* wird -1 zurückgegeben.
*/
static int positionImAlphabet(String zeichen) {
int verschluesselt = -1;
if(zeichen.length() == 1) {
String alphabet = "abcdefghijklmnopqrstuvwxyz";
verschluesselt = alphabet.indexOf(zeichen.toLowerCase());
if(verschluesselt != -1) {
verschluesselt++;
}
}
return verschluesselt;
}
/**
* Die Methode buchstabeAnPosition gibt für Zahlen zwischen
* 1 und 26 Buchstaben zurück, die an der entsprechenden
* Position im Alphabet stehen. Für alle anderen Zahlen
* wird eine leere Zeichenkette zurückgegeben.
*/
static String buchstabeAnPosition(int position) {
String buchstabe = "";
String alphabet = "abcdefghijklmnopqrstuvwxyz";
if(position > 0 && position < 27) {
buchstabe += alphabet.substring(position - 1, position);
}
return buchstabe;
}
static void teste() {
// Getestet wird immer mit Verschiebung von 3
int verschiebung = 3;
String[][] testfälle = new String[4][2];
testfälle[0][0] = "abc";
testfälle[0][1] = "def";
testfälle[1][0] = "Hallo";
testfälle[1][1] = "kdoor";
testfälle[2][0] = "xyz";
testfälle[2][1] = "abc";
testfälle[3][0] = "Mister X, das wird nichts!";
testfälle[3][1] = "plvwhu a, gdv zlug qlfkwv!";
boolean alleTestsBestanden = true;
for (String[] testfall : testfälle) {
String ergebnis = verschluessele(testfall[0], verschiebung);
if(ergebnis.equals(testfall[1])) {
println("+", "green");
} else {
println("Test fehlgeschlagen", "red");
println("Testfall: " + testfall[0]);
println("Erwartet wurde:");
println(testfall[1]);
println("Erhalten:");
println(ergebnis);
alleTestsBestanden = false;
}
}
println(alleTestsBestanden ? "Alle Tests bestanden!" : "Einige Tests wurden nicht bestanden.");
}
}
Caesar.teste();
Ergänze die Funktion verschluessele
. Die Datei beinhaltet Tests – lass sie regelmäßig laufen und überprüfe, ob deine Implementierung funktioniert. Verwende bei Bedarf die beiden in der Klasse enthaltenen Methoden position_im_alphabet
und buchstabe_an_position
.
import doctest
alphabet = 'abcdefghijklmnopqrstuvwxyz'
def verschluessele(text: str, verschiebung: int) -> str:
"""
Nimmt Texte (Zeichenketten) und eine Verschiebung entgegen und gibt
entsprechend verschlüsselte Texte zurück. Die Texte werden in Kleinbuchstaben
ausgeben, Leerzeichen und Satzzeichen bleiben erhalten.
>>> verschluessele('abc', 3)
'def'
>>> verschluessele('Hallo', 1)
'ibmmp'
>>> verschluessele('xyz', 3)
'abc'
>>> verschluessele('Mister X, das wird nichts!', 3)
'plvwhu a, gdv zlug qlfkwv!'
>>> verschluessele('plvwhu a, gdv zlug qlfkwv!', 23)
mister x, das wird nichts!
"""
# Ersetze pass durch deinen Code
pass
def position_im_alphabet(zeichen: str) -> int:
"""
Die Funktion positionImAlphabet gibt für einzelne
Buchstaben deren Position (1..26) im Alphabet zurück.
Für Umlaute, andere Zeichen und längere Zeichenketten
wird -1 zurückgegeben.
>>> position_im_alphabet('c')
3
>>> position_im_alphabet('Z')
26
>>> position_im_alphabet(' ')
-1
>>> position_im_alphabet('abc')
-1
"""
verschluesselt = -1
if len(zeichen) == 1 and zeichen.lower() in alphabet:
verschluesselt = alphabet.index(zeichen.lower()) + 1
return verschluesselt;
def buchstabe_an_position(position: int) -> str:
"""
Die Funktion buchstabe_an_position gibt für Zahlen zwischen
1 und 26 Buchstaben zurück, die an der entsprechenden
Position im Alphabet stehen. Für alle anderen Zahlen
wird eine leere Zeichenkette zurückgegeben.
>>> buchstabe_an_position(2)
'b'
>>> buchstabe_an_position(25)
'y'
>>> buchstabe_an_position(27)
''
>>> buchstabe_an_position(-1)
''
"""
if 0 < position < 27:
return alphabet[position - 1]
return ''
if __name__ == '__main__':
doctest.testmod()
Lege die beiden Klassen Caesar
und CaesarTest
in je eigenen Dateien in einem Verzeichnis an. (Lass dir ggf. von deiner IDE helfen, die Abhängigkeiten für die Verwendung von Junit aufzulösen.)
Ergänze die Methode verschluessele
in der Klasse Caesar
. Lass den Test regelmäßig laufen und überprüfe, ob deine Implementierung funktioniert.
Verwende bei Bedarf die beiden in der Klasse enthaltenen Methoden positionImAlphabet
und buchstabeAnPosition
. Die Klasse enthält eine Methode println
, die die Methode System.out.println
ersetzt.
Datei Caesar.java
:
class Caesar {
static String verschluessele(String text, int verschiebung) {
StringBuilder verschlusselterText = new StringBuilder();
// Hier kommt dein Code hin:
return verschlusselterText.toString();
}
/**
* Die Methode positionImAlphabet gibt für einzelne
* Buchstaben deren Position (1..26) im Alphabet zurück.
* Für Umlaute, andere Zeichen und längere Zeichenketten
* wird -1 zurückgegeben.
*/
static int positionImAlphabet(String zeichen) {
int verschluesselt = -1;
if(zeichen.length() == 1) {
String alphabet = "abcdefghijklmnopqrstuvwxyz";
verschluesselt = alphabet.indexOf(zeichen.toLowerCase());
if(verschluesselt != -1) {
verschluesselt++;
}
}
return verschluesselt;
}
/**
* Die Methode buchstabeAnPosition gibt für Zahlen zwischen
* 1 und 26 Buchstaben zurück, die an der entsprechenden
* Position im Alphabet stehen. Für alle anderen Zahlen
* wird eine leere Zeichenkette zurückgegeben.
*/
static String buchstabeAnPosition(int position) {
String buchstabe = "";
String alphabet = "abcdefghijklmnopqrstuvwxyz";
if(position > 0 && position < 27) {
buchstabe += alphabet.substring(position - 1, position);
}
return buchstabe;
}
static void println(Object o) {
System.out.println(o.toString());
}
}
Datei CaesarTest.java
:
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class CaesarTest {
@Test
void testVerschluessele() {
assertEquals("def", Caesar.verschluessele("abc", 3));
assertEquals("ibmmp", Caesar.verschluessele("Hallo", 1));
assertEquals("abc", Caesar.verschluessele("xyz", 3));
assertEquals("plvwhu a, gdv zlug qlfkwv!", Caesar.verschluessele("Mister X, das wird nichts!", 3));
assertEquals("mister x, das wird nichts!", Caesar.verschluessele("plvwhu a, gdv zlug qlfkwv!", 23));
}
@Test
void testPositionImAlphabet() {
assertEquals(3, Caesar.positionImAlphabet("c"));
assertEquals(26, Caesar.positionImAlphabet("Z"));
assertEquals(-1, Caesar.positionImAlphabet(" "));
assertEquals(-1, Caesar.positionImAlphabet("abc"));
}
@Test
void testBuchstabeAnPosition() {
assertEquals("b", Caesar.buchstabeAnPosition(2));
assertEquals("y", Caesar.buchstabeAnPosition(25));
assertEquals("", Caesar.buchstabeAnPosition(27));
assertEquals("", Caesar.buchstabeAnPosition(-1));
}
}
Tipps für Online-IDE Java #
Tipp 1
Nutze eine for
-Wiederholung, um jeden Buchstaben des Eingabetextes durchzugehen. Lege vor dem Wiederholungsblock eine Variable verschluesselterText
(oder ähnlich) an, die im Wiederholungsblock nach und nach ergänzt wird.
So initialisiert du die Variable gleich mit einer leeren Zeichenkette:
String verschlusselterText = "";
Tipp 2
Eine vereinfachte for
-Wiederholung benötigt z.B. ein Array, um darüber zu iterieren (jedes Element einmal aufzurufen.) Um die übergebene Zeichenkette in ein Array zu verwandeln, in dem jeder Buchstabe einzeln (wieder als Zeichenkette) enthalten ist, kannst du die split
-Methode nutzen:
String[] textArray = text.split("");
Tipp 3
Um jedes Zeichen der Reihe nach einmal aufzurufen, kannst du die vereinfachte for
-Wiederholung nutzen:
for (String zeichen : textArray) {
// Hier wandelst du jedes einzelne Zeichen um
// und hängst es an die vorbereitete Variable
// verschluesselterText
}
Tipp 4
Die Methode positionImAlphabet
liefert dir die Position des Zeichens im Alphabet zurück, oder -1
, falls du keinen Buchstaben (oder einen Umlaut o.ä.) übergibst. Es bietet sich eine Fallunterscheidung an, die sonstige Zeichen unverändert übernimmt:
int position = positionImAlphabet(zeichen);
if(position != -1) {
// Hier muss das Zeichen verschlüsselt werden und
// an verschluesselterText gehängt werden.
} else {
// Falls das Zeichen kein Buchstabe ist,
// wird es einfach so angehängt
verschluesselterText += zeichen;
}
Tipp 5
Wie verschlüsseln wir nun Zeichen?
Ersteinmal könntest du ausprobieren, die Verschiebung zur Position einfach hinzuzuzählen. Aus der errechneten Position erzeugen wir mit buchstabeAnPosition
wieder Buchstaben:
int positionVerschluesselt = position + verschiebung;
verschluesselterText += buchstabeAnPosition(positionVerschluesselt);
Einige Tests werden noch fehlschlagen…
Tipp 6
Soll erfolgreich über den Buchstaben z hinaus verschoben werden, hilft die Modulo-Operation (%
), die den Rest berechnet. Weil unsere Methode positionImAlphabet
Positionen zwischen 1 und 26 zurückgibt (und nicht zwischen 0 und 25), müssen wir ein wenig hin- und herrechnen:
int positionVerschluesselt = ((position - 1 + verschiebung) % 26) + 1;
verschluesselterText += buchstabeAnPosition(positionVerschluesselt);
Lösungsvorschlag
static String verschluessele(String text, int verschiebung) {
String verschluesselterText = "";
String[] textArray = text.split("");
for (String zeichen : textArray) {
int position = positionImAlphabet(zeichen);
if(position != -1) {
int positionVerschluesselt = ((position - 1 + verschiebung) % 26) + 1;
verschluesselterText += buchstabeAnPosition(positionVerschluesselt);
} else {
verschluesselterText += zeichen;
}
}
return verschluesselterText;
}
Tipps für Python #
Tipp 1
Nutze eine for
-Wiederholung, um jeden Buchstaben des Eingabetextes durchzugehen. Lege vor dem Wiederholungsblock eine Variable text_verschluesselt
(oder ähnlich) an, die im Wiederholungsblock nach und nach ergänzt wird.
So initialisiert du die Variable gleich mit einer leeren Zeichenkette:
text_verschluesselt = ''
Tipp 2
Um jedes Zeichen der Reihe nach einmal aufzurufen, kannst du eine for
-Wiederholung nutzen:
for zeichen in text:
# Hier wandelst du jedes einzelne Zeichen um
# und hängst es an die vorbereitete Variable
# text_verschluesselt
Tipp 3
Die Funktion position_im_alphabet
liefert dir die Position des Zeichens im Alphabet zurück, oder -1
, falls du keinen Buchstaben (oder einen Umlaut o.ä.) übergibst. Es bietet sich eine Fallunterscheidung an, die sonstige Zeichen unverändert übernimmt:
vielleicht_position = position_im_alphabet(zeichen)
if not vielleicht_position == -1:
# Hier muss das Zeichen verschlüsselt werden und
# an text_verschluesselt gehängt werden.
else:
# Falls das Zeichen kein Buchstabe ist,
# wird es einfach so angehängt
text_verschluesselt += zeichen
Tipp 4
Wie verschlüsseln wir nun Zeichen?
Ersteinmal könntest du ausprobieren, die Verschiebung zur Position einfach hinzuzuzählen. Aus der errechneten Position erzeugen wir mit buchstabe_an_position
wieder Buchstaben:
position_verschluesselt = vielleicht_position + verschiebung
verschluesselt += buchstabe_an_position(position_verschluesselt)
Einige Tests werden noch fehlschlagen…
Tipp 5
Soll erfolgreich über den Buchstaben z hinaus verschoben werden, hilft die Modulo-Operation (%
), die den Rest berechnet. Weil unsere Methode position_im_alphabet
Positionen zwischen 1 und 26 zurückgibt (und nicht zwischen 0 und 25), müssen wir ein wenig hin- und herrechnen:
position_verschluesselt = ((vielleicht_position - 1 + verschiebung) % 26) + 1
zeichen_verschluesselt = buchstabe_an_position(position_verschluesselt)
text_verschluesselt += zeichen_verschluesselt
Lösungsvorschlag
def verschluessele(text: str, verschiebung: int) -> str:
"""
Nimmt Texte (Zeichenketten) und eine Verschiebung entgegen und gibt
entsprechend verschlüsselte Texte zurück. Die Texte werden in Kleinbuchstaben
ausgeben, Leerzeichen und Satzzeichen bleiben erhalten.
>>> verschluessele('abc', 3)
'def'
>>> verschluessele('Hallo', 1)
'ibmmp'
>>> verschluessele('xyz', 3)
'abc'
>>> verschluessele('Mister X, das wird nichts!', 3)
'plvwhu a, gdv zlug qlfkwv!'
"""
text_verschluesselt = ''
for zeichen in text:
vielleicht_position = position_im_alphabet(zeichen)
if not vielleicht_position == -1:
position_verschluesselt = ((vielleicht_position - 1 + verschiebung) % 26) + 1
zeichen_verschluesselt = buchstabe_an_position(position_verschluesselt)
text_verschluesselt += zeichen_verschluesselt
else:
text_verschluesselt += zeichen
return text_verschluesselt
Tipps für Java #
Tipp 1
Nutze eine for
-Wiederholung, um jeden Buchstaben des Eingabetextes durchzugehen.
Um zum Schluss den verschlüsselten Text als Zeichenkette zurückzugeben, ist bereits ein StringBuilder-Objekt verschluesselterText
angelegt. Mit der Methode append
lassen sich dem StringBuilder-Objekt etwas anhängen:
verschlusselterText.append("Ich bin eine Zeichenkette");
Tipp 2
Eine vereinfachte for
-Wiederholung benötigt z.B. ein Array, um darüber zu iterieren (jedes Element einmal aufzurufen.) Um die übergebene Zeichenkette in ein Array zu verwandeln, in dem jeder Buchstabe einzeln (wieder als Zeichenkette) enthalten ist, kannst du die split
-Methode nutzen:
String[] textArray = text.split("");
Tipp 3
Um jedes Zeichen der Reihe nach einmal aufzurufen, kannst du die vereinfachte for
-Wiederholung nutzen:
for (String zeichen : textArray) {
// Hier wandelst du jedes einzelne Zeichen um
// und hängst es an die vorbereitete Variable
// verschluesselterText
}
Tipp 4
Die Methode positionImAlphabet
liefert dir die Position des Zeichens im Alphabet zurück, oder -1
, falls du keinen Buchstaben (oder einen Umlaut o.ä.) übergibst. Es bietet sich eine Fallunterscheidung an, die sonstige Zeichen unverändert übernimmt:
int position = positionImAlphabet(zeichen);
if(position != -1) {
// Hier muss das Zeichen verschlüsselt werden und
// an verschluesselterText gehängt werden.
} else {
// Falls das Zeichen kein Buchstabe ist,
// wird es einfach so angehängt
verschluesselterText.append(zeichen);
}
Tipp 5
Wie verschlüsseln wir nun Zeichen?
Ersteinmal könntest du ausprobieren, die Verschiebung zur Position einfach hinzuzuzählen. Aus der errechneten Position erzeugen wir mit buchstabeAnPosition
wieder Buchstaben:
int positionVerschluesselt = position + verschiebung;
verschluesselterText.append(buchstabeAnPosition(positionVerschluesselt));
Einige Tests werden noch fehlschlagen…
Tipp 6
Soll erfolgreich über den Buchstaben z hinaus verschoben werden, hilft die Modulo-Operation (%
), die den Rest berechnet. Weil unsere Methode positionImAlphabet
Positionen zwischen 1 und 26 zurückgibt (und nicht zwischen 0 und 25), müssen wir ein wenig hin- und herrechnen:
int positionVerschluesselt = ((position - 1 + verschiebung) % 26) + 1;
verschluesselterText.append(buchstabeAnPosition(positionVerschluesselt));
Lösungsvorschlag
static String verschluessele(String text, int verschiebung) {
StringBuilder verschluesselterText = new StringBuilder();
String[] textArray = text.split("");
for (String zeichen : textArray) {
int position = positionImAlphabet(zeichen);
if(position != -1) {
int positionVerschluesselt = ((position - 1 + verschiebung) % 26) + 1;
verschluesselterText.append(buchstabeAnPosition(positionVerschluesselt));
} else {
verschluesselterText.append(zeichen);
}
}
return verschluesselterText.toString();
}