JavaScripts › Verschlüsselungen
Bacon-Chiffre
Ersetzt jeden Buchstaben durch eine Fünfergruppe aus A und B — und versteckt die Botschaft auf Wunsch unsichtbar in einem harmlosen Trägertext.
Francis Bacon beschrieb 1605 ein Verfahren, das anders gedacht ist als alle anderen auf diesen Seiten: Es soll nicht verbergen, was in einer Nachricht steht, sondern dass überhaupt eine Nachricht da ist. Jeder Buchstabe wird dazu durch eine Gruppe aus fünf Zeichen ersetzt, die nur zwei Zustände kennen — bei Bacon A und B. Aus dem A wird AAAAA, aus dem B AAAAB, aus dem C AAABA und so weiter.
Fünf Stellen mit je zwei Möglichkeiten ergeben 32 Kombinationen, genug für die 26 Buchstaben. Bacon hatte damit rund 250 Jahre vor der Telegrafie und 340 Jahre vor dem ersten Computer die Idee des binären Codes aufgeschrieben — es ist im Kern dasselbe, was in jedem Rechner passiert, nur mit A und B statt 0 und 1. Der Zusammenhang wird beim Binärcode-Wandler noch deutlicher.
Der eigentliche Trick ist der dritte Knopf. Die beiden Zustände müssen nämlich nicht A und B heißen — sie können alles sein, was zwei Formen hat: zwei Schriftarten, zwei Tintenfarben oder, wie hier, Groß- und Kleinbuchstaben. Tragt unten eine geheime Botschaft und einen harmlosen Trägertext ein, und das Script verteilt die Botschaft über die Groß- und Kleinschreibung des Trägers. Heraus kommt ein Text, der nur nachlässig getippt aussieht — und niemand vermutet darin eine Nachricht. Solche Verfahren heißen Steganografie, im Unterschied zur Kryptografie, die ein Geheimnis offen als Geheimnis zeigt.
Als Verschlüsselung taugt Bacon für sich genommen nichts: Wer das Verfahren kennt, liest die Fünfergruppen direkt ab. Sinnvoll wird es erst zusammen mit einem echten Verfahren — erst Caesar oder das Vigenère-Quadrat anwenden, dann das Ergebnis im Trägertext verstecken. Verwandt ist der Morsecode, der ebenfalls mit zwei Zeichen auskommt, aber unterschiedlich lange Gruppen benutzt.
Der Trägertext braucht mindestens fünf Buchstaben je Zeichen der Botschaft. Nur A–Z werden verschlüsselt.
So funktioniert das Script
Das Script hat zwei Ebenen: Die untere übersetzt Buchstaben in Fünfergruppen und zurück, die obere verteilt diese Gruppen über die Groß- und Kleinschreibung eines Trägertextes. Beide Ebenen benutzen dieselbe Umrechnung.
for (let stelle = 4; stelle >= 0; stelle--) {
gruppe += (nummer >> stelle) & 1 ? "B" : "A";
}
Hier wird eine Zahl binär geschrieben. >> verschiebt die Bits einer Zahl nach rechts, & 1 holt das unterste Bit heraus. Die Schleife läuft von der fünften Stelle abwärts und fragt für jede: Ist dieses Bit gesetzt? Für das G — Nummer 6, binär 00110 — kommt so AABBA heraus. Wer das lieber ohne Bit-Rechnung möchte, kann auch nummer.toString(2).padStart(5, "0") nehmen und anschließend die Nullen und Einsen gegen A und B tauschen; das Ergebnis ist identisch.
nummer = nummer * 2 + (gruppe.charAt(i) === "B" ? 1 : 0);
Der Rückweg kommt ohne Bit-Operatoren aus. Man liest die Gruppe von links nach rechts und verdoppelt bei jedem Schritt das bisherige Ergebnis, bevor die neue Stelle addiert wird — genau so, wie man auch im Zehnersystem aus den Ziffern 4, 7 und 2 die Zahl 472 baut, nur eben mit dem Faktor 2 statt 10. Aus AABBA wird so 0, 0, 1, 3, 6.
const sauber = text.toUpperCase().replace(/[^A-Z]/g, "");
Das Verfahren kennt nur 26 Buchstaben. Diese Zeile wirft alles andere weg: Das Dach ^ am Anfang einer eckigen Klammer bedeutet „alles außer" — hier also „alles außer A bis Z". Umlaute und Leerzeichen verschwinden damit ersatzlos, die Umwandlung ist also bewusst nicht verlustfrei. Historisch war das kein Nachteil: Bacons Alphabet hatte sogar nur 24 Zeichen, weil I und J sowie U und V zusammenfielen.
if (/[a-zA-ZäöüÄÖÜ]/.test(zeichen) && gesetzt < bits.length) {
ergebnis += bits.charAt(gesetzt) === "B"
? zeichen.toUpperCase()
: zeichen.toLowerCase();
gesetzt++;
}
Das ist das Verstecken. Der Trägertext wird Zeichen für Zeichen durchlaufen; jeder Buchstabe verbraucht ein Bit der Botschaft und wird entsprechend groß oder klein geschrieben. Leerzeichen und Satzzeichen zählen nicht mit und wandern unverändert durch — sonst könnte der Empfänger die Bits nicht wiederfinden, denn er wendet dieselbe Regel an. Der Zähler gesetzt merkt sich, wie viele Bits schon untergebracht sind; ist der Träger zu kurz, meldet das Script es, statt eine halbe Botschaft auszugeben.
bits += zeichen === zeichen.toUpperCase() ? "B" : "A";
Das Auslesen ist die Umkehrung in einer Zeile: Ein Buchstabe, der seiner eigenen Großschreibung gleicht, war groß geschrieben und steht für B. Probiert es aus — versteckt eine Botschaft, kopiert das Ergebnis ins Trägerfeld und drückt „Botschaft im Träger finden".
Zum Anpassen: Statt Groß- und Kleinschreibung könnt ihr jedes andere Merkmalspaar nehmen, das ein Text hat. Ein einfaches und unauffälligeres wäre ein normales gegen ein schmales Leerzeichen; für eine Webseite ließen sich auch zwei kaum unterscheidbare Schriftschnitte einsetzen. Das Prinzip bleibt dasselbe — nur die eine Zeile, die das Merkmal setzt, ändert sich.
Script für die eigene Homepage
Kopiert euch den kompletten Code und fügt ihn an der Stelle eurer Seite ein, an der das Script erscheinen soll. Er läuft ohne weitere Dateien und ohne fremde Server.