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.
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\) (vgl. 7.2.3). - 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.
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.
