Skip to content

Latest commit

 

History

History
102 lines (70 loc) · 2.95 KB

File metadata and controls

102 lines (70 loc) · 2.95 KB

TUCTF 2016 – Beatz for Dayz

Problem

Flag hidden in a FLAC file.

Solution

Download the FLAC file into a SampledSoundList[] instance. This sound primitive contains samples that represent the amplitude and it is easy to work with.

sampledSoundList = Import[
  "http://ctf.asciioverflow.com/static/uploads/63811a1fd9fc936477585d0c67415fb0/2108dd8652498e179096eecf746ea8301c3cbe0b.flac",
  "SampledSoundList"];

We can easily view the waveform easily with Sound[]. Notice there is a strange bump in one channel of the waveform. We will isolate it and see what it looks like.

Sound[sampledSoundList]

sound

Next, extract the left and right channels of the audio. Mathematica's destructuring can be used to unpack the list.

{left, right} = First@sampledSoundList;

We can plot the waveforms manually too.

GraphicsColumn[ListLinePlot[#, PlotRange -> {-1, 1}] & /@ {left, right}]

ListLinePlot

Take difference of the channels by simply subtracting one list (channel) from the other. Examine the result by plotting it.

ListLinePlot[left - right, PlotRange -> {-1, 1}]

difference

Examine the interesting portion of the waveform by graphing a portion of the list.

ListLinePlot[(left - right)[[39150 ;; 39300]], PlotRange -> {-1, 1.2}]

difference-segment

Isolate the interesting portion of the signal by taking the Threshold[] of it at 0.5 and stretching the rest of signal to the minimum and maximum range with Unitize[]. This will produce a list of only 1's and 0's.

diff = Unitize@Threshold[left - right, {"Hard", 0.5}];

Graph the new list.

ListLinePlot[diff[[39150 ;; 39300]]]

difference-unitized

Split[] the waveform into a list of segments where the value is the same (1 or 0). Then replace each sublist with the value repeated in the list and the length of the run of values.

{First[#], Length[#]} & /@ Split@diff
{{0, 39156}, {1, 4}, {0, 1}, {1, 4}, {0, 4}, {1, 4}, {0, 1}, {1, 4},
{0, 1}, {1, 4}, {0, 4}, {1, 1}, {0, 1}, {1, 4}, {0, 1}, {1, 1}, {0, 4},
{1, 1}, {0, 1}, {1, 1}, {0, 1}, {1, 1}, {0, 4}, {1, 1}, {0, 8}, {1, 1},
{0, 1}, {1, 1}, {0, 4}, {1, 1}, {0, 1}, {1, 1}, {0, 1}, {1, 1}, {0, 8},
{1, 1}, {0, 1}, {1, 1}, {0, 1}, {1, 4}, {0, 1}, {1, 1}, {0, 4}, {1, 1},
{0, 1}, {1, 1}, {0, 1}, {1, 4}, {0, 4}, {1, 4}, {0, 1}, {1, 1}, {0, 11},
{1, 580}, {0, 166708}}

Convert each value and run to a character representation of its Morse value.

StringJoin[({First[#], Length[#]} & /@ Split@diff)[[2 ;; -4]] /. {
   {1, 4} -> "-",
   {1, 1} -> ".",
   {0, 1} -> "",
   {0, 4} -> " ",
   {0, 8} -> "  "}]
-- --- .-. ... .  .. ...  ..-. ..- -.

Mathematica cannot decode Morse Code directly, so use WolframAlpha instead.

morse-WolframAlpha