Frequenzanalyse: Wir analysieren eine der Lieblingsaufgaben der Teilnehmer der Online-Phase von NeoQUEST-2020


Heute veröffentlichen wir den Wright-Up-Auftrag NeoQUEST-2020 , über den unsere Teilnehmer geschrieben haben: „4 Task mega cool“ und „Die beste Aufgabe der Olympiade“.
Trotz der scheinbaren Einfachheit haben nur 8 Personen diese Aufgabe erledigt! Und jetzt können Sie ihn besser kennenlernen - willkommen unter Katze!


Die Teilnehmer sind daher eingeladen, die Audioaufnahme herunterzuladen . Eine Minute Hören reicht aus, um zu verstehen, dass Morsecode hier nicht einmal riecht, genau wie bedeutungsvolle Wörter in der Audioaufnahme auch nicht beachtet werden. Deshalb beenden wir die Folter, indem wir zuhören und beginnen, den Klang genauer zu betrachten. Zum Beispiel mit der guten alten (und freien) Audacity . Wir öffnen die Audioaufnahme und achten auf ihre Struktur: Zwischen den Tastenanschlägen herrscht absolute Stille (jemand hatte Glück mit den Arbeitsbedingungen, Sie haben keine Telefonanrufe und chatten Kollegen für immer!), Was bedeutet, dass es nicht schwierig sein wird, jeden einzelnen Tastenanschlag durch Filtern von Abschnitten zu extrahieren mit Null Signalamplitude.



Okay, lass es uns tun. Jetzt haben wir zwei Dinge: ein „Array“ mit 100.500 Klicks und die Hoffnung, dass es unter diesen Sounds Wiederholungen gibt - nur dann kann man sagen, dass „die X-Taste N-mal und die Y-Taste M-mal gedrückt wurde“. Nachdem alle anfänglichen Daten analysiert wurden, bleibt die Frage zu beantworten: "Wozu führen uns solche Aussagen, vorausgesetzt, die Audioaufnahme dauert 10 Minuten?". Ja, das stimmt, es ist Zeit, die klassische Frequenzanalyse aufzudecken . Nun, wir testen unsere Theorie mit Python, Numpy und Scikits.audiolab (für die Verarbeitung von Sound können Sie jedes andere Paket und sogar jede Sprache mit dem gleichen Erfolg auswählen).
Um die Umgebung einzurichten, können Sie die folgenden Befehle ausführen (dies funktioniert definitiv unter Ubuntu 19.10):

$ sudo apt-get install -y python python-dev python-pip python-setuptools libsndfile-dev python-numpy
$ pip install --upgrade pip
$ pip install scikits.audiolab


Jetzt implementieren wir den Test unserer Annahme in mehreren Codezeilen, die den primitivsten Weg verwenden, um den Klickgeräusch zu identifizieren - anhand der Summe der Werte des entsprechenden Numpy-Arrays:

get list of separated ‘clicks’
data, fs, enc = scikits.audiolab.wavread(filename)
data = data.ravel()
clicks = [list(g) for k, g in groupby(data, lambda x: x != 0) if k]

# calculate number of unique ‘clicks’ and their frequences
freqs = dict() 
cypher_test = list()
for click in clicks:
    value = np.sum(np.array(click), dtype = np.float32)
    cypher_test.append(value)
    if value not in freqs:
        freqs[value] = 1
    else:
        freqs[value] += 1


Das im Diagramm gezeigte Ergebnis der Codeausführung - wie die Hitze eines Freudenfeuers mitten in einem nuklearen Winter - kann die Seele nur erwärmen: Mindestens 27 eindeutige Klicks und sogar das Erscheinungsbild der Verteilung wecken das Vertrauen, dass die Frequenzanalyse nicht zwecklos sein wird.



Laut Wikipedia und anderen zuverlässigeren Quellen bilden 26 englische Buchstaben, die in absteigender Reihenfolge ihres Auftretens sortiert sind, die etaoinshrdlcumwfgypbvkjxqz- Reihe . Dazu natürlich eine Lücke, die eine führende Position einnimmt. Du weißt was zu tun ist! Wieder verwenden wir mehrere Zeilen primitiven Codes, um jeden Ton zu vergleichen, indem wir auf seinen Buchstaben klicken (in der Häufigkeit des Auftretens) und den ersten Austausch durchführen:

COMMON_FREQ_ALPHABET = { 0:' ', 1:'e', 2:'t', 3:'a', 4:'o', 5:'i', 6:'n', 7:'s', 8:'h', 9:'r', 10:'d', 11:'l', 12:'c', 13:'u', 14:'m',15:'w', 16:'f', 17:'g', 18:'y', 19:'p', 20:'b', 21:'v', 22:'k', 23:'j', 24:'x', 25:'q', 26:'z' }

# calculate key
key = dict()
index = 0
for freq in sorted(freqs.items(), key=operator.itemgetter(1),reverse=True):
    key[freq[0]] = COMMON_FREQ_ALPHABET[index]
    index +=1

# replace sounds according the key
partly_plain_text = ""
for elem in cypher_test:
	partly_plain_text += key[elem]


Nach dem Ersetzen der Frequenzanalyse erhalten wir den folgenden Text:

onlineayvinf saty stw vltn selg kird moaher csctl ncmertl we tnswer utn metscre gtll saory retl enocfh worb ltrfe tvvetr tftin vltue scn satra zero gtua t gew rotd sveuitl vroklem etsa ketcay idet who lef ipere saone retuh vrodcua uca fipe reuord scre aoob jcesaion oca dcrinf vtss dry ahen show low lisa kltub okxeuas low lifha old frow wtauh aowtrd suhool my frow well heta norah mile mcsa resa tdd tmonf yocnf kesa kird beev kird gooa smtll wts bnow oca utme uca vltna some when bnow awo how dripe tftin vca while oaher some ocr letrn satr mincae digger men scrgtues infor retd hetrd lisa rtin utll vora yes whta idet ftme bind new him old deev eta keftn keftn or socah ahe some mtv tkle sonf i metn saory yetr fold mile dtrb eqtmvle world gish tfe geel ahocstnd one mile his ky ahe tkope ahose uhildren rtin gcll gtll tnimtl ury vocnd vltue ahose shora jciub where ahocfh saood fopern sorry i gorfoa i vromised ao lend yoc my uode fea ia grom my fiahck neoscveruoder htnd ahese binf wind utrb new vossikle tdd grom saood lifha down lipe mincae rotd foa satra gire ahocfh ahose some scn aia iaeai aet iaeai aia iaeai aet iaeai aia iaeai aet iaeai aia iaeai aet iaeai aia iaeai aet iaeai aia iaeai aet iaeai ucn shoa ucn shoa ucn shoa ucn shoa ucn shoa ucn shoa ucn shoa ucn shoa ucn shoa ucn shoa ucn shoa ucn shoa ucn shoa shtbe wtpe ltke nibe shtbe wtpe ltke nibe shtbe wtpe ltke nibe shtbe wtpe ltke nibe shtbe wtpe ltke nibe shtbe wtpe htn mtd dou htn mtd dou htn mtd dou htn mtd dou htn mtd dou htn mtd dou htn mtd dou htn mtd dou htn mtd dou htn dou gipe yet gipe yet gipe yet gipe yet gipe yet gipe yet gipe yet gipe yet gipe yet gipe yet gipe yet gipe yet gipe

Es sieht ein wenig nach etwas Sinnvollem aus, aber einzelne Wörter werden definitiv erraten. Suchen Sie nacheinander nach Wörtern, bei denen klar ist, welcher Ersatz vorgenommen werden soll:
  1. moaher -> Mutter und Antwort -> Antwort, d.h. a und t müssen vertauscht werden;
  2. larfe → groß und selg → selbst, d.h. f und g müssen vertauscht werden;
  3. kird → Vogel, d.h. k wird durch b ersetzt und onlinetyving → onlinetyping, d.h. v durch p ersetzen;
  4. messen → messen und enocgh → genug, d.h. u und c müssen vertauscht werden.

Infolge dieser Manipulationen wird der Text dramatisch verändert, und sein erstes Wort erklärt die mangelnde Konnektivität: Die Audioaufnahme wurde während des Übens von Typografie auf einem Tastatursimulator aufgezeichnet. Eh, der Besitzer des Schlüssels hat sich offensichtlich nicht auf die Apokalypse vorbereitet! Wir können uns für ihn freuen, wahrscheinlich fingert er jetzt sehr schnell und kratzt den Schnee, der den Ausgang seiner Zuflucht blockiert hat. Aber was geht uns das an? Wir werden den Text überblicken, vielleicht gibt es noch etwas Nützliches.

onlinetyping stay saw plan self bird mother usual numeral we answer can measure fall story real enough worb large appear again place sun start zero fact a few road special problem east beauty idea who leg ipere stone reach product cut gipe record sure toob juestion out during pass dry then show low list blacb obxects low light old grow watch toward school my grow well heat north mile must rest add among young best bird beep bird foot small was bnow out came cut plant some when bnow two how dripe again put while other some our learn star minute differ men surfaces ingor read heard list rain call port yes what idea game bind new him old deep eat began began or south the some map able song i mean story year gold mile darb eqample world fish age feel thousand one mile his by the abope those children rain full fall animal cry pound place those short juicb where though stood gopern sorry i forgot i promised to lend you my code get it from my github neosupercoder hand these bing wind carb new possible add from stood light down lipe minute road got start fire though those some sun tit iteti tea iteti tit iteti tea iteti tit iteti tea iteti tit iteti tea iteti tit iteti tea iteti tit iteti tea iteti cun shot cun shot cun shot cun shot cun shot cun shot cun shot cun shot cun shot cun shot cun shot cun shot cun shot shabe wape labe nibe shabe wape labe nibe shabe wape labe nibe shabe wape labe nibe shabe wape labe nibe shabe wape han mad doc han mad doc han mad doc han mad doc han mad doc han mad doc han mad doc han mad doc han mad doc han doc fipe yea fipe yea fipe yea fipe yea fipe yea fipe yea fipe yea fipe yea fipe yea fipe yea fipe yea fipe yea fipe

Es scheint, wir hatten Glück: Während des Trainings war jemand abgelenkt und schrieb eine Rettungsnachricht an seinen Freund, wahrscheinlich in einem Messenger: Entschuldigung, ich habe vergessen, dass ich versprochen habe, Ihnen meinen Code zu leihen, um ihn von meinem Github-Neosupercoder zu bekommen. Das Lesen der Korrespondenz eines anderen ist natürlich nicht gut, aber hier ist eine hundertprozentige Ausnahme, wir haben mehr als genug für diese Informationen bezahlt. Wir gehen zu Github und suchen das Repository nach Benutzername:



Erfolg! Es bleibt nur die einzige Datei aus dem Repository "Neo-Medizin" zu lesen:



Hurra! Jetzt sind wir die glücklichen Besitzer des Schlüssels!
Vor uns - die Analyse anderer Aufgaben NeoQUEST-2020 - werden wir unsere Leser nicht mit Selbstisolation langweilen lassen!

All Articles