Mit Zeichen rechnen
char:ein Zeichen ist eine Zahl (Unicode):'A'= 65 …'Z'= 90.- Nummer:
c - 'A'macht aus einem Großbuchstaben eine Zahl von 0 bis 25. - Verschieben:
+ k, dann% 26— über Z hinaus geht es bei A weiter. - Zurück:
+ 'A'und die Umwandlung(char), dennchar + intergibtint. - Entschlüsseln:
- kkann negativ werden; Javas%liefert dann einen negativen Rest — deshalb vorher+ 26. - Andere Zeichen:Leerzeichen und Satzzeichen bleiben unverändert.
Herleitung:
'X' = 88'A'k = 5 landet man hinter Z.'C'(char) ((c - 'A' + k) % 26 + 'A').Stelle Schlüssel k und Position i ein und verfolge, wie ein Buchstabe durch die Rechenkette läuft. Schalte dann auf „Entschlüsseln“ und vergleiche die Formel ohne und mit + 26.
Halte fest: Verschlüsseln ist die Kette − 'A', + k, % 26, + 'A'. Beim Entschlüsseln wird die Zahl vor % 26 negativ — ohne + 26 entstehen Zeichen vor dem A.
Zeichenrechnung: Ein char ist eine Zahl (Unicode): 'A' = 65 … 'Z' = 90.
Verschlüsseln: c - 'A' macht den Buchstaben zur Zahl 0 bis 25, dann + k, % 26, + 'A' und die Umwandlung (char), weil char + int ein int ergibt.
Entschlüsseln: - k kann negativ werden und Javas % liefert dann einen negativen Rest, deshalb vorher + 26.
Andere Zeichen: Leerzeichen und Satzzeichen bleiben unverändert.
Implementieren und testen
- Methodenkopf:
static String verschluesseln(String klar, int k)— Text rein, Text raus. - Schleife:Zeichen für Zeichen mit
charAt(i), Ergebnis mit+an eine Zeichenkette hängen. - Entschlüsseln:nichts neu programmieren — Verschieben um
26 - khebt das Verschieben umkauf. - Vigenère:Schlüssel wechselt mit der Position:
k = schluessel.charAt(i % m) - 'A',m= Schlüssellänge. - XOR:
(char) (c ^ s)— dieselbe Methode ver- und entschlüsselt, denn \(c \oplus s \oplus s = c\). - Testen:Rundreise
entschluesseln(verschluesseln(t, k), k)muss für alle 26 Schlüssel wiedertliefern; dazu Grenzfällek = 0,'Z', Leerzeichen, leere Zeichenkette.
public class Caesar {
public static String verschluesseln(String klar, int k) {
String geheim = "";
for (int i = 0; i < klar.length(); i++) {
char c = klar.charAt(i);
if (c >= 'A' && c <= 'Z') {
c = (char) ((c - 'A' + k) % 26 + 'A');
}
geheim = geheim + c;
}
return geheim;
}
public static String entschluesseln(String geheim, int k) {
return verschluesseln(geheim, 26 - k % 26);
}
public static void main(String[] args) {
String g = verschluesseln("ZUG UM ACHT", 3);
System.out.println(g); // CXJ XP DFKW
System.out.println(entschluesseln(g, 3)); // ZUG UM ACHT
for (int k = 0; k < 26; k++) { // Rundreise-Test
if (!entschluesseln(verschluesseln("XYZ", k), k).equals("XYZ")) {
System.out.println("Fehler bei k = " + k);
}
}
System.out.println(('C' - 'A' - 3) % 26); // -1 (Java-Rest!)
}
}
Caesar in Java: verschlüsseln (char) ((c - 'A' + k) % 26 + 'A'), entschlüsseln (char) ((c - 'A' - k + 26) % 26 + 'A') — geprüft mit der Rundreise für alle Schlüssel.
Entschlüsseln: Verschieben um 26 - k hebt das Verschieben um \(k\) auf.
Vigenère: k = schluessel.charAt(i % m) - 'A', \(m\) ist die Schlüssellänge.
XOR: (char) (c ^ s) ver- und entschlüsselt, denn \(c \oplus s \oplus s = c\).
Testen: Die Rundreise muss für alle 26 Schlüssel den Text zurückliefern; dazu Grenzfälle prüfen.
Allgemeine Hinweise
% ist kein mod
In Java gilt -3 % 26 == -3, nicht 23. Mathematisch wäre der Rest immer positiv — im Programm muss man das mit + 26 selbst sicherstellen.
char plus int ist int
'A' + 2 ergibt die Zahl 67. Ohne (char) hängt geheim + ('A' + 2) die Ziffern „67“ an statt des Buchstabens C.
Die Rundreise verrät alles
Ein einziger Test mit k = 3 übersieht Randfälle. Eine Schleife über alle Schlüssel und einen Text mit X, Y, Z und Leerzeichen deckt Fehler beim Umlauf sofort auf.
