Analyse de fréquence: nous analysons l'une des tùches favorites des participants de la scÚne en ligne de NeoQUEST-2020


Aujourd'hui, nous publions la mission Wright-Up NeoQUEST-2020 , à propos de laquelle nos participants ont écrit: «4 tùches méga cool» et «La meilleure tùche de l'Olympiade».
Malgré l'apparente simplicité, seulement 8 personnes ont terminé cette tùche! Et maintenant, vous pouvez mieux le connaßtre, pour cela - bienvenue sous cat!


Les participants sont donc invitĂ©s Ă  tĂ©lĂ©charger l' enregistrement audio . Une minute d'Ă©coute suffit pour comprendre que le code Morse ne sent mĂȘme pas ici, tout comme les mots significatifs dans l'enregistrement audio ne sont pas non plus observĂ©s. Par consĂ©quent, nous mettons fin Ă  la torture en Ă©coutant et commençons Ă  regarder le son plus en dĂ©tail. Par exemple, en utilisant le bon vieux (et gratuit) Audacity . Nous ouvrons l'enregistrement audio et prĂȘtons attention Ă  sa structure: entre les frappes, il y a un silence absolu (quelqu'un a eu de la chance avec les conditions de travail, vous n'avez pas d'appels tĂ©lĂ©phoniques et discutez avec des collĂšgues pour toujours!), Ce qui signifie qu'il ne sera pas difficile d'extraire chaque frappe en filtrant les sections avec une amplitude de signal nulle.



D'accord, faisons-le. Maintenant, nous avons deux choses: un «tableau» dans lequel il y a 100 500 clics, et l'espoir que parmi ces sons il y a des rĂ©pĂ©titions - alors seulement on peut dire que «la touche X a Ă©tĂ© pressĂ©e N fois et la touche Y Ă©tait M fois.» Ainsi, toutes les donnĂ©es initiales ont Ă©tĂ© analysĂ©es, il reste Ă  rĂ©pondre Ă  la question «à quoi nous mĂšnera un tel ensemble de dĂ©clarations, Ă  condition que l'enregistrement audio dure 10 minutes?». Oui, c'est vrai, il est temps de dĂ©couvrir l' analyse de frĂ©quence classique . Eh bien, nous testons notre thĂ©orie en utilisant python, numpy et scikits.audiolab (pour le traitement du son, vous pouvez choisir n'importe quel autre package et mĂȘme langage avec le mĂȘme succĂšs).
Pour configurer l'environnement, vous pouvez exécuter les commandes suivantes (cela fonctionne certainement sur 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


Maintenant, nous implémentons le test de notre hypothÚse dans plusieurs lignes de code qui utilise le moyen le plus primitif pour identifier le son du clic - par la somme des valeurs du tableau numpy correspondant:

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


Le rĂ©sultat de l'exĂ©cution du code, montrĂ© sur le diagramme - comme la chaleur d'un feu de joie au milieu d'un hiver nuclĂ©aire - ne peut que rĂ©chauffer l'Ăąme: au moins 27 clics uniques, et mĂȘme l'apparence de la distribution inspire confiance que l'analyse de frĂ©quence ne sera pas futile.



Selon Wikipedia et d'autres sources plus fiables, 26 lettres de la langue anglaise, triées par ordre décroissant d'occurrence, forment la série etaoinshrdlcumwfgypbvkjxqz . De plus, bien sûr, un écart, qui occupe une position de leader. Vous savez ce qu'il faut faire! Encore une fois, nous utilisons plusieurs lignes de code primitif pour comparer chaque son en cliquant sur sa lettre (en fréquence d'occurrence) et effectuer le remplacement initial:

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]


AprÚs avoir remplacé l'analyse de fréquence, nous obtenons le texte suivant:

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

Cela ressemble un peu Ă  quelque chose de significatif, mais les mots individuels sont dĂ©finitivement devinĂ©s. Recherchez sĂ©quentiellement les mots dans lesquels il est Ă©vident quel remplacement doit ĂȘtre effectuĂ©:
  1. moaher -> mĂšre et rĂ©ponse -> rĂ©ponse, c.-Ă -d. a et t doivent ĂȘtre interchangĂ©s;
  2. larfe → grand et selg → soi, c'est-Ă -dire f et g doivent ĂȘtre interchangĂ©s;
  3. kird → oiseau, i.e. k est remplacĂ© par b et onlinetyving → onlinetyping, c'est-Ă -dire v remplacer par p;
  4. mesure → mesure et engagement → assez, c'est-Ă -dire u et c doivent ĂȘtre interchangĂ©s.

À la suite de ces manipulations, le texte est radicalement transformĂ©, et son premier mot explique le manque de connectivitĂ©: l'enregistrement audio a Ă©tĂ© enregistrĂ© tout en pratiquant la typographie sur un simulateur de clavier. Eh, le propriĂ©taire de la clĂ© ne se prĂ©parait manifestement pas Ă  l'apocalypse! .. On peut ĂȘtre content pour lui, sans doute maintenant qu'il doigte trĂšs vite, ratisse la neige qui a bloquĂ© la sortie de son refuge. Mais qu'est-ce que cela nous fait? Nous allons parcourir le texte, peut-ĂȘtre y a-t-il encore quelque chose d'utile.

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

Il semble que nous ayons eu de la chance: pendant la formation, quelqu'un a Ă©tĂ© distrait et a Ă©crit un message de rĂ©cupĂ©ration Ă  son ami, probablement dans un messager: dĂ©solĂ©, j'ai oubliĂ© que j'ai promis de vous prĂȘter mon code, rĂ©cupĂ©rez-le sur mon github neosupercoder. Bien sĂ»r, lire la correspondance de quelqu'un d'autre n'est pas bon, mais il y a une exception Ă  cent pour cent, nous avons payĂ© plus que suffisant pour cette information. Nous allons sur github et recherchons le rĂ©fĂ©rentiel par nom d'utilisateur:



SuccÚs! Il ne reste plus qu'à lire le seul fichier du référentiel "néo-médecine":



Hourra! Maintenant, nous sommes les heureux propriétaires de la clé!
A venir - l'analyse des autres tĂąches NeoQUEST-2020 - nous ne laisserons pas nos lecteurs s'ennuyer avec l'auto-isolement!

All Articles