Im letzten Artikel hast du gelernt, wie man eine Nachricht durch Sortieren einer Liste beliebiger Dinge codieren kann. Musik besteht aus Melodien, die gewissermaßen; Notenlisten sind. Warum nicht mal ein Lied komponieren, dessen Melodie ein Text ist?
Entscheiden müssen wir uns nur für die Menge der Noten, die im Lied vorkommen sollen. Weil es Factorial(count)
aufzählbare Permutationen gibt, erlauben mehr verschiedene Noten ein größeres Alphabet für die geheime Nachricht. Dieser Artikel wird sich nicht um Harmonielehre und Komposition kümmern. Für den Anfang werden wir eine ganze chromatische Tonleiter aufmischen, um ein langes oder einige kurze Wörter zu codieren. Für längere Texte kann man mehrere Melodieteile verketten.
Ein einfaches Beispiel: Eine Tonleiter hat 12 Noten, zwei davon machen 24 Noten, das reicht für ein “hello world”. Der Nachrichtentext wid als ein einziger BigInteger
behandelt. Die leere Nachricht ist ‘0’, die Default-Reihenfolge der Noten:
Ich habe mifür 42 verschiedene Zeichen entschieden: a-z 0-9 .:() und Leerzeichen. Mit diesem Alphabet wird die numerische Repräsentation von “hello world” folgendermaßen berechnet:
h = 7 w = 22 e = 4 o = 14 l = 11 r = 17 l = 11 l = 11 o = 14 d = 3 ------------------------ 7 * (42^10) h + 4 * (42^9) e + 11 * (42^8) l + 11 * (42^7) l + 14 * (42^6) o + 36 * (42^5) [space] + 22 * (42^4) w + 14 * (42^3) o + 17 * (42^2) r + 11 * (42^1) l + 3 * (42^0) d ------------------------ = 121297199112622725
Mit dieser Zahl lässt sich der zuvor erklärte Algorithmus füttern, mit der chromatischen Tonleiter als Trägerliste. (Für Nicht-Musiker: C C# D D# E F F# G G# A H B c c# d d# e f f# g g# a h b.)
Das Ergebnis sieht so aus:
d d# D e f A G# f# F H g F# C# E g# c# B a G D# c C h b
Die größmögliche numerische Nachricht (und damit die Länge der Textnachricht) ist durch Factorial(countNotes)
beschänkt. Um mehr Text zu codieren könnte man entweder mehr Noten verwenden - oder die numerischen Werte kleiner halten. Im obigen Beispiel verursachte die Basis 42 extrem große Werte. Beschränkt man die Zeichen auf a-z und Leerzeichen, so ist die Basis 27 und der Text “hello world” hat den Wert 1474967912327400. Das heißt, wir können einen längeren Text in einer Melodie derselben Länge speichern.
7 * (27^10) h + 22 * (27^4) w + 4 * (27^9) e + 14 * (27^3) o + 11 * (27^8) l + 17 * (27^2) r + 11 * (27^7) l + 11 * (27^1) l + 14 * (27^6) o + 3 * (27^0) d + 36 * (27^5) [space] --------------------------------------------------- = 1474967912327400
Eine Melodie aus reinen Viertelnoten klingt schnell langweilig. Aber wenn die Noten einmal sortiert sind, kann man überall Duplikate einfügen. Alle Wiederholungen werden vor dem Decodieren entfernt. Da Zeit keine Rolle spielt (im Prototypen noch nicht), dürfen Vierten nach Belieben in Achtel aufgespalten werden. Nichts davon beeinflusst die codierte Nachricht. Hier sind ein paar Varianten von “coding in c sharp” (Nummer 201255931456816565832252 mit dem 27-Zeichen-Alphabet).
Text: “coding in c sharp”
Tonleiter: beginnt mit A
Melodie: f e c# b g a G h F# H g# G# A D c f# E F C d C# B d# D#
Text: “coding in c sharp”
Tonleiter: beginnt mit D
Melodie: H A F# e c d C d# b D# c# C# D g F B a h f G f# E G# g#
Text: “coding in c sharp”
Tonleiter: beginnt mit F
Melodie: c# c A g d# f D# f# D F# e E F h G# d C C# g# H a G B b
Text: “coding in c sharp”
Tonleiter: beginnt mit G
Melodie: dis d B a f g F gis E Gis fis Fis G C H e D Dis h c b A cis Cis
Die Demo codiert in vier Schritten Text als Musik:
Natuürlich kann man auch eine Melodie zurück in Text decodieren:
Das Programm wurde für eine Vorführung geschrieben. Daher hat es ein paar versteckte Funktionen, welche die Zuschauer nicht mit sichtbaren Buttons oder Menüs verwirren.
Manche Geeks fragten mich, was die Textbedeutung von pi
sei. Für solche Situationen können Text- und Zahlenfeld vertauscht werden: Doppelklicke auf das Feld “Content numeric”. Es wird dann entsperrt und die eingegebenen Zahlen werden zu Text decodiert.
Um den Inhalt eines Textfelds zu speichern, setze den Fokus in das Feld und drücke Ctrl+Y. Der Text wird dann an die Datei clipboard.txt im exe-Verzeichnis angehängt.
Die Anwendung zeigt das Ergebnis in Notenname und malt gleichzeitig die Noten. Weil aber nur die Notennamen später wieder eingetippt und decodiert werden können, können nur diese in die Zwischenablage bzw. clipboard.txt kopiert werden. Um die Noten zu speichern hilft ein Linksklick auf das Bild. Es wird dann als PNG-Datei im exe-Verzeichnis abgelegt.
Die Melodie, wie sie vom “Play”-Button gepiept wird, kann mit einem Rechtsklick auf das Bild gespeichert werden. Sie wird dann als WAV-Datei im exe-Verzeichnis abgelegt.
Mit einigen Kombinationen von mono-Version und Audio-System ist Console.Beep
unbrauchbar. Wenn bei dir so ein Problem auftritt, definiere die Präprozessor-Variable IsMono
in Form1.cs.
#define IsMono
Anstatt zu piepen, speichert das Programm dann den Klang in einer temporären Datei und lässt ihn von sox abspielen. Es sollte keinen sicht-/hörbaren Unterschied zum normalen Verhalten geben.
Die Demo-Anwendung zeigt nur die grundlegende Idee. Vielleicht hast du Lust es zu erweitern, um lange Textnachrichten in mehrteilige Melodien aufzuteilen, eine Tonart zu garantieren, nur Harmonien in vorgegebene Melodien einzufügen und so weiter. Im Prinzip gibt es kaum Grenzen, deinen Instrumentalstücken einen geheimen Subtext zu verleihen.