Diese Coding-Spur leitet durch einfache Programmieraufgaben im Themenfeld Kryptologie - sowohl aus dem Bereich der Kryptographie als auch der Kryptoanalyse.
Der römische Feldherr und Kaiser Julius Cäsar (100-44 v. Chr.) hat für seine militärische und staatliche Kommunikation bei Bedarf eine Verschlüsselung eingesetzt. Dabei hat er das Alphabet um 3 Buchstaben verschoben: dabei wird z.B. A zu D und Y zu B.
Diese Chiffre ist eine symmetrische monoalphabetische Substitutionschiffre. Symmetrisch, weil der Schlüssel für die Verschlüsselung wie auch die Entschlüsselung gleich ist und monoalphabetisch, weil ein Buchstabe immer durch das selbe Zeichen ersetzt wird.
Aufgabe: Erweitern Sie den untenstehenden Basiscode in Etappen, damit Sie zum Schluss eine Chiffrierhilfe nach folgendem Vorbild erhalten:
(schluessel[i] + rot) % 26
rotSlider.value()
let schluessel = [];
let s = 25;
let rotSlider;
let rot = 13;
function setup() {
createCanvas(652, 320);
rotSlider = createSlider(0, 25, 3, 1);
rotSlider.position(width-210, 105);
rotSlider.style("width", "200px");
for (let i=0; i<26; i++) {
schluessel.push(i);
}
console.log(schluessel);
textSize(16);
}
function draw() {
background(245);
translate(1, 0);
// Klartext Buchstabenleiste
for (let i=0; i<26; i++) {
noFill();
stroke(70);
rect(i*s, s, s, s);
fill(40, 40, 200);
noStroke();
textAlign(CENTER, CENTER);
text(char(i+65), i*s, s, s, s);
textAlign(LEFT);
text("Klartext", 3, 0.6*s);
// Verbindungslinien
}
// Geheimtext Buchstabenleiste
// Platzhalter Codierung
}
Mit einem Ersetzungscode verschlüsselte Nachrichten lassen sich einer Häufigkeitsanalyse unterziehen. Ein derartiges Analysetool wollen wir programmieren.
Aufgabe: Erweitern Sie den Basiscode mit Hilfe folgender Etappen:
charsDE
.
let myTextarea;
let mySlider;
let aktIndex;
let charsDE = [6.166, 2.293, 2.773, 4.447, 17.756, 1.725, 2.689, 3.743, 7.886, 0.239, 1.446, 4.019, 2.846, 9.742, 3.125, 1.405, 0.083, 6.831, 6.444, 6.216, 3.869, 0.893, 1.471, 0.299, 0.296, 1.267];
let b = 24;
function setup() {
createCanvas(640, 320);
mySlider = createSlider(0, 25, 7, 1);
mySlider.position(width-210, 15);
mySlider.style("width", "200px");
myTextarea = createElement("textarea", "Aus nur Buchstaben bestehender Text für die Analyse hierhin kopieren oder hier eingeben");
myTextarea.style("width", "630px");
myTextarea.style("height", "60px");
textSize(24);
textAlign(CENTER);
}
function draw() {
background(245);
aktIndex = mySlider.value();
fill(80, 80, 255);
textSize(16);
text(aktIndex, width-225, 32);
// alle Buchstaben anzeigen
fill(30);
for (let i=0; i<26; i= i+1) {
text(char(i + 65), 20+i*b, 70);
}
// durchschnittliche Häufigkeit der Buchstaben aus dem Array charsDE ausgeben
// Eingabetext aufbereiten
let eingabeText = myTextarea.value();
eingabeText = eingabeText.replaceAll(' ');
eingabeText = eingabeText.toUpperCase();
// Anzahl Vorkommen eines einzelnen Buchstabens im Eingabetext zählen
let anzahl = 0;
for (let j=0; j < eingabeText.length; j=j+1) {
if (eingabeText.charCodeAt(j)-65 == aktIndex) {
anzahl = anzahl + 1;
}
}
// Berechnungen
fill(90);
textSize(16);
text(anzahl, 20+aktIndex*b, 100);
let haeufigkeit = anzahl / eingabeText.length;
text(nf(haeufigkeit, 1, 2), 20+aktIndex*b, 125);
// Häufigkeit als Säule ausgeben
fill(80, 80, 255, 127);
let hoehe = map(haeufigkeit, 0, 0.2, 0, 160);
rect(10+aktIndex*b, height-hoehe, 20, hoehe);
}
Die Cäsar Verschiebechiffre kann durch Umstellung (Permutation) des Geheimtextalphabetes zu einer Ersetzungschiffre verbessert werden. Neu wird jedes Zeichen des Klartextalphabetes mit einem bestimmten, fixen Buchstaben chiffriert.
Aufgabe: Erweitern Sie den untenstehenden Basiscode in Etappen, damit Sie zum Schluss eine Chiffrierhilfe folgender Art erstellen können:
let schluesselSet = [];
let schluessel = [];
let s = 25;
let rot = 3;
let btnInput;
let myInput;
let cWort = '';
function setup() {
createCanvas(652, 480);
myInput = createInput();
myInput.style("width", "380px");
btnInput = createButton('Wort setzen...');
btnInput.mousePressed(myEvent);
myEvent();
}
function draw() {
background(245);
translate(1, 0);
textSize(16);
for (let i=0; i<26; i++) {
// Klartext Buchstabenleiste
noFill();
stroke(70);
rect(i*s, s, s, s);
fill(40, 40, 200);
noStroke();
textAlign(CENTER, CENTER);
text(char(i+65), i*s, s, s, s);
textAlign(LEFT);
text("Klartext", 3, 15);
// Geheimtext Buchstabenleiste
noFill();
stroke(70);
rect(i*s, 3*s, s, s);
fill(200, 40, 40);
textAlign(CENTER, CENTER);
noStroke();
text(char(schluessel[i]+65), i*s, 3*s, s, s);
textAlign(LEFT);
text("Geheimtext", 3, 110);
stroke(170);
// Verbindungslinien
line(i*s+s/2, 53, i*s+s/2, 72);
}
// Koordinaten-Ursprung verschieben
textAlign(CENTER);
translate(width/2, 0.63*height);
// Scheibe Klartext
fill(240, 240, 255);
stroke(170);
circle(0, 0, 230);
noStroke();
for (i=0; i<26; i=i+1) {
translate(100, 0);
rotate(HALF_PI);
fill(40, 40, 200);
textSize(24);
text(char(i+65), 0, 0);
rotate(-HALF_PI);
translate(-100, 0);
rotate(TWO_PI/26.0);
// Mittelpunkt
noFill();
stroke(70);
circle(0, 0, 10);
}
}
function myEvent() {
schluesselSet = [];
for (let i=0; i<26; i++) {
schluesselSet.push(i);
}
schluessel = [];
cWort = myInput.value().toUpperCase();
//Eingegebene Buchstaben setzen
for (let i = 0; i > cWort.length; i=i+1) {
let pos = cWort.charAt(i);
let buchstabenPos = cWort.charCodeAt(i)-65;
if (schluesselSet[buchstabenPos] != -1) {
schluessel.push(buchstabenPos);
schluesselSet[buchstabenPos] = -1;
}
}
// nicht verwendete Buchstaben anfügen, d.h. wenn != -1
for (let i = 0; i < schluesselSet.length; i=i+1) {
if (schluesselSet[i] != -1) {
schluessel.push(i);
}
}
}
Das von Blaise de Vigenère (1523-1596) entwickelte Verfahren verschlüsselt ein Buchstabe in der Regel mit verschiedenen Buchstaben und wird entsprechend als polyalphabetisches Chiffrierverfahren bezeichnet. Dieses Verfahren galt lange Zeit als unknackbar.
Aufgabe I: Studieren Sie die Funktionsweise des Vigenère Verfahrens mit Hilfe der folgenden Simulation: Vigenère Simulation.
Aufgabe II: Analysieren und Verwenden Sie den folgenden Sketch:
let aktKeyCode = aktKey.charCodeAt(i%aktKey.length)-65
let btnCode;
let btnDecode;
let inputArea;
let outputArea;
let schluessel;
let aktIndex;
function setup() {
noCanvas();
createElement("h2", "Vigenère Chiffre");
createP('Schlüssel:');
schluessel = createInput("KEY");
schluessel.style("width", "300px");
btnCode = createButton("codieren...");
btnCode.mousePressed(chiffrieren);
btnDecode = createButton("decodieren...");
btnDecode.mousePressed(dechiffrieren);
createP('Eingabe:');
inputArea = createElement("textarea", "Eingabe");
inputArea.style("width", "630px");
inputArea.style("height", "60px");
createP('Ausgabe:');
outputArea = createElement("textarea", "---");
outputArea.style("width", "630px");
outputArea.style("height", "60px");
let absaetze = selectAll('p');
for (let i = 0; i < absaetze.length; i += 1) {
absaetze[i].style("margin", "0.5em 0 0.1em 0");
}
textSize(24);
textAlign(CENTER);
}
function draw() {
background(245);
aktIndex = mySlider.value();
fill(80, 80, 255);
textSize(16);
text(aktIndex, width-235, 32);
// alle Buchstaben anzeigen
fill(30);
for (let i=0; i<26; i= i+1) {
text(char(i + 65), 20+i*24, 70);
}
}
function chiffrieren() {
vigenere(true);
}
function dechiffrieren() {
vigenere(false);
}
function vigenere(richtung) {
let aktKey = schluessel.value();
aktKey = aktKey.replaceAll(' ', '');
aktKey = aktKey.toUpperCase();
schluessel.value(aktKey);
let aktInput = inputArea.value();
aktInput = aktInput.replaceAll(' ', '');
aktInput = aktInput.toUpperCase();
inputArea.value(aktInput);
let geheimtext = "";
if (aktKey.length == 0) {
alert("Bitte Schlüssel erfassen.");
} else {
if ( aktInput.length == 0) {
alert("Bitte Eingabetext erfassen.");
} else {
for (let i= 0; i < aktInput.length; i=i+1) {
let aktKeyCode = aktKey.charCodeAt(i%aktKey.length)-65;
let aktCharCode = aktInput.charCodeAt(i)-65;
if (richtung == true) {
geheimtext = geheimtext + char((aktCharCode + aktKeyCode)%26 + 65) ;
} else {
geheimtext = geheimtext + char((aktCharCode - aktKeyCode+26)%26 + 65) ;
}
}
outputArea.value(geheimtext);
}
}
}
Auch bei der Vigenère Chiffre hilft eine Häufigkeitsanalyse. Der preussische Major Friedrich Wilhelm Kasiski veröffentlichte 1863 die entscheidende Idee zum Brechen des Vigenère Codes. Er suchte den Geheimtext nach sogenannten Dubletten ab, sich wiederholenden Buchstabenfolgen unterschiedlicher Länge. Aus den beobachteten Abständen errechnete er den grössten gemeinsamen Teiler und deutete diesen als wahrscheinliche Schlüssellänge. Studieren Sie diese Idee mit Hilfe der folgenden Aufgaben:
fs in ksw