Introduction
In Steganography 19 - The Order of the Code, you learned how to encode messages by sorting a collection of arbitrary things. Music is made of melodies which are collections of notes. Why not compose a song to encode a text in the melody?
All you need to define is the set of notes you want to use in the song. As there are Factorial(count)
enumerable permutations, more possible notes mean a bigger alphabet for the secret message. In this article, we won't spend time on harmonics and composition. We will mix up a whole chromatic scale to encode one long or a few short words. For longer messages, you can concatenate several melodies.
Hello World
Let's start with a simple example. There are 12 notes per scale, two scales have 24 notes, that will be enough for "hello world". The message text is treated as a BigInteger
. An empty message is '0', which is the default sorting of the notes:
I decided to allow 42 different characters: a-z 0-9 .:() and space. Using this alphabet, the numeric representation of "hello world" is calculated like that:
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
This number can be fed into the algorithm explained earlier, with a chromatic scale being the carrier list. (Reminder for non-musicians: C C# D D# E F F# G G# A H B c c# d d# e f f# g g# a h b.)
The result looks like this:
d d# D e f A G# f# F H g F# C# E g# c# B a G D# c C h b
Less Letters, More Words
The maximum numeric message (and therefore the length of the text message) is limited by Factorial(countNotes)
. To encode more text, we can either use more notes or keep the numeric values smaller. In the above example, the base of 42 produced extremely high values. If you restrict the characters to a-z and space, the base is 27 and the text "hello world" has a value of only 1474967912327400. That means, we can store a longer text in a melody of the same length.
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
Rhythm - Just for Fun
A melody of plain quarter notes may sound boring. But once the notes are sorted, you can insert duplicates wherever you like. All repetitions will be removed before decoding. As time is not important (yet, in this prototype), you can split quarters into quavers at random. Nothing of that will affect the encoded message. Here are a few versions of "coding in c sharp" (which is number 201255931456816565832252 with an alphabet of 27 characters).
- Text: "coding in c sharp"
- Scale: starts with A
- Melody: 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"
- Scale: starts with D
- Melody: 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"
- Scale: starts with F
- Melody: 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"
- Scale: starts with G
- Melody: dis d B a f g F gis E Gis fis Fis G C H e D Dis h c b A cis Cis
The Demo Application
The demo lets you encode text as music in four steps:
- Select an offset for the chromatic scale (it's called tonality for future use).
- Choose an alphabet. The characters of the selected one are displayed in the title bar.
- Enter your message.
- Mix your melody. If the result is not nice enough, check "Random melody" and mix again and again until it sounds alright.
Of course, you can also decode a melody back to text:
- Select the offset that has been used for encoding.
- Choose the same alphabet.
- Enter the note names in the result box.
- Un-mix the notes to plain text.
The application was written for a presentation, that's why there are a few hidden features that don't disturb the listeners with visible buttons or menus.
Number Games
Some geeks asked me what is the textual meaning of pi
. For such situations, the text and number fields can be swapped: double click the field "Content numeric". It then becomes editable and the number you enter will be decoded to text.
Quick Notes
To save the content of a TextBox
for later use, focus the box and press Ctrl+Y. The text will be appended to clipboard.txt in the executable's directory.
Save the Picture
The application displays the result as note names and drawn notes synchronously. But as only the note names can be entered and decoded again, only those can be copied to the Clipboard. Anyway, there's a way to grab the picture: left click the PictureBox. The notes will be saved to a PNG file in the executable's directory.
Save the Sound
The melody beeped by the "Play" button can also be saved: right click the PictureBox. The sound will be saved to a WAV file in the executable's directory.
Workaround for Mono/Linux
With some combinations of Mono versions and audio drivers, Console.Beep
stays silent. If you encounter such a problem, define the pre-compiler variable IsMono
in Form1.cs.
#define IsMono
Instead of beeping, the application will then save the sound to a temporary file and have SoX play it. There should be no visible/audible difference to the usual behaviour.
Outlook
The demo application shows only the basic idea. Maybe I'll enhance it to split long messages into several melody parts, ensure a certain tonality, add harmonies to a given melody instead of generating a random one, and so on. There are no limits for composers to add secret content to their songs.