Análisis de frecuencia: analizamos una de las tareas favoritas de los participantes de la etapa en línea de NeoQUEST-2020


Hoy estamos publicando la tarea Wright-Up NeoQUEST-2020 , sobre la cual nuestros participantes escribieron: "4 Task mega cool" y "La mejor tarea de la Olimpiada".
A pesar de la aparente simplicidad, ¡solo 8 personas completaron esta tarea! Y ahora puedes conocerlo mejor, por esto, ¡bienvenido bajo gato!


Por lo tanto, los participantes están invitados a descargar la grabación de audio . Un minuto de escucha es suficiente para comprender que el código Morse ni siquiera huele aquí, al igual que tampoco se observan palabras significativas en una grabación de audio. Por lo tanto, terminamos la tortura escuchando y comenzamos a mirar el sonido con más detalle. Por ejemplo, usando el viejo (y gratis) Audacity . Abrimos la grabación de audio y prestamos atención a su estructura: entre las pulsaciones de teclas hay un silencio absoluto (alguien tuvo suerte con las condiciones de trabajo, ¡no tiene llamadas telefónicas y chatea con colegas para siempre!), Lo que significa que no será difícil extraer cada pulsación de tecla filtrando secciones con amplitud de señal cero.



Ok, hagámoslo. Ahora tenemos dos cosas: una "matriz" en la que hay 100.500 clics, y la esperanza de que entre estos sonidos haya repetitivos: solo entonces será posible decir que "la tecla X se presionó N veces, y la tecla Y fue M veces". Por lo tanto, todos los datos iniciales han sido analizados, queda por responder la pregunta "¿a qué nos llevará tal conjunto de declaraciones, siempre que la grabación de audio dure 10 minutos?". Sí, es cierto, es hora de descubrir el análisis de frecuencia clásico . Bueno, probamos nuestra teoría usando python, numpy y scikits.audiolab (para procesar el sonido, puede elegir cualquier otro paquete e incluso el idioma con el mismo éxito).
Para configurar el entorno, puede ejecutar los siguientes comandos (definitivamente funciona en 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


Ahora implementamos la prueba de nuestra suposición en varias líneas de código que utilizan la forma más primitiva para identificar el sonido del clic, mediante la suma de los valores de la matriz numpy correspondiente:

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


El resultado de la ejecución del código, que se muestra en el diagrama, como el calor de una hoguera en medio de un invierno nuclear, no puede sino calentar el alma: al menos 27 clics únicos, e incluso la apariencia de la distribución inspira confianza en que el análisis de frecuencia no será inútil.



Según Wikipedia y otras fuentes más confiables, 26 letras del idioma inglés, ordenadas en orden decreciente de ocurrencia, forman la serie etaoinshrdlcumwfgypbvkjxqz . Además, por supuesto, una brecha, que ocupa una posición de liderazgo. ¡Sabes qué hacer! Nuevamente, usamos varias líneas de código primitivo para comparar cada sonido haciendo clic en su letra (en frecuencia) y realizamos el reemplazo inicial:

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]


Después de reemplazar el análisis de frecuencia, obtenemos el siguiente texto: se

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

parece un poco a algo significativo, pero las palabras individuales definitivamente se adivinan. Busque secuencialmente palabras en las que sea obvio qué reemplazo debe hacerse:
  1. moaher -> madre y tnswer -> respuesta, es decir ayt deben intercambiarse;
  2. larfe → grande y selg → propio, es decir f y g deben intercambiarse;
  3. kird → pájaro, es decir k se reemplaza por b y onlinetyving → onlinetyping, es decir v reemplazar con p;
  4. meascre → medir y enocgh → suficiente, es decir u y c deben intercambiarse.

Como resultado de estas manipulaciones, el texto se transforma dramáticamente, y su primera palabra explica la falta de conectividad: la grabación de audio se grabó mientras se practicaba la tipografía en un simulador de teclado. ¡Eh, el dueño de la llave claramente no se estaba preparando para el apocalipsis! Podemos estar felices por él, probablemente ahora está tocando muy rápido, rastrillando la nieve que ha bloqueado la salida de su refugio. ¿Pero qué es esto para nosotros? Revisaremos el texto, quizás todavía haya algo útil.

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

Parece que tuvimos suerte: durante el entrenamiento, alguien se distrajo y le escribió un mensaje de rescate a su amigo, probablemente en algún mensajero: lo siento, olvidé que prometí prestarle mi código de mi neosupercoder github. Leer la correspondencia de otra persona, por supuesto, no es bueno, pero hay una excepción del cien por ciento, pagamos más que suficiente por esta información. Vamos a github y buscamos el repositorio por nombre de usuario:



¡Éxito! Solo queda leer el único archivo del repositorio "neo-medicina":



¡Hurra! ¡Ahora somos los felices propietarios de la llave!
A continuación, el análisis de otras tareas NeoQUEST-2020, ¡no dejaremos que nuestros lectores se aburran del autoaislamiento!

All Articles