Python Challenge: Niveles 0-6

Python Challenge es una página con retos a resolver utilizando Python. Es posible resolverlos utilizando otros lenguajes, aunque la finalidad del juego es aprender más sobre librerías y funcionalidades específicas de Python.

En este post voy a enseñar las soluciones a los 7 primeros niveles de este Challenge. Conforme siga avanzando, publicaré las soluciones a niveles posteriores. Puedes encontrar el código de las soluciones en Github.

Nivel 0: Warming up

Este es un nivel bastante sencillo, en el que sólo tendrás que calcular la potencia que se muestra en la imagen, y sustituir en la URL el 0 por el valor de esta.

Nivel 1: What about making trans?

De nuevo, un nivel muy sencillo, en el que el propio título de la página nos dice qué hacer. Nos dan un texto cifrado por rotación, y qué rotación tenemos que hacer, usando maketrans para solucionarlo. Al hacerlo, obtenemos este texto:

i hope you didnt translate it by hand. thats what computers are for. doing it in by hand is inefficient and that's why this text is so long. using string.maketrans() is recommended. now apply on the url.

Hacemos el mismo maketrans sobre la URL, y llegamos al siguiente nivel.

Nivel 2: OCR

El propio nivel nos dice que miremos el código fuente. Lo miramos y encontramos dos comentarios, el primero de ellos:

find rare characters in the mess below:

Justo después, encontramos una masa de caracteres sin sentido. Nos quedamos sólo con las letras de la masa, y obtenemos la clave para el siguiente nivel.

Nivel 3: Re

La pista nos sugiere que busquemos una letra minúscula, rodeada de exactamente 3 letras mayúsculas a cada lado. Utilizando expresiones regulares hacemos la búsqueda [^A-Z][A-Z]{3}([a-z])[A-Z]{3}[^A-Z] y encontramos unas cuantas letras, que juntas forman la solución a este nivel.

Nivel 4: Follow the chain

Al hacer click en la imagen, llegamos a una página terminada en ?nothing=12345 con el siguiente texto:

and the next nothing is 44827

Al cambiar el número en la URL, llegamos a otra página igual, que de nuevo apunta a otro número distinto. Parece que podríamos llevarnos así todo el día, por lo que habrá que hacer uso de una librería de peticiones HTTP, como es el caso de urllib (incluida en Python) o requests.

Por medio de la navegación nos encontraremos que hay que dividir entre 2 uno de los códigos. Quitando esto el nivel no tiene mayor complicación, seguimos 250 páginas y llegaremos al enlace al siguiente nivel.

Nivel 5: Peak hell

La pista es que pronunciemos el título del nivel, que suena sospechosamente parecido a Pickle, la librería de serialización de objetos en Python.

En el código fuente encontramos un archivo pickle. Al importarlo y examinarlo un poco, se ve que es una lista de líneas de un texto. Cada línea, en vez de ser una lista de caracteres, es una lista de pares (carácter, repeticiones). Al reconstruir el texto, obtenemos un bonito ASCII art:

ASCII art solución al nivel 5 del Python Challenge

Nivel 6: Now there are pairs

Este problema es bastante parecido al 4. Nos muestran una imagen de una cremallera (zip en inglés), y al cambiar la extensión de la imagen de png a zip, encontramos un archivo comprimido con muchos archivos txt y un readme, que reza:

welcome to my zipped list.
hint1: start from 90052
hint2: answer is inside the zip

Navegamos por los archivos del mismo modo que en el nivel 4, esta vez usando la librería zipfile, hasta llegar al final, que en este caso no es la solución, sino el texto "collect the comments".

Como en los archivos zip existe un campo de comentarios para los archivos, vamos guardando los comentarios de cada uno conforme navegamos. Al juntarlos todos, de nuevo obtenemos un mensaje en ASCII art.

En este caso, el ASCII art está pensado para despistar. La palabra que forma no es relevante, pero sí lo son los caracteres que forman las letras.

Puedes encontrar la solución a los siguientes niveles en el post con las soluciones de los niveles 7-14.

No hay comentarios

Place: arte colaborativo llevado al extremo

En abril de 2017, una curiosa historia se materializó en Reddit. Por el día de los inocentes, realizaron un pequeño experimento: crear un lienzo en blanco para que los usuarios lo editaran de forma anónima, llamado Place.

Las reglas eran simples. Cada usuario podía escoger un píxel de una paleta de 16 colores para ponerlo en cualquier parte del lienzo. Podían poner píxeles de los colores que quisieran, pero tenían que esperar 5 minutos antes de poner el siguiente.

Tras 72 horas, el resultado fue impresionante. Una pieza de arte colaborativo que sorprendió hasta a sus creadores. De un lienzo en blanco y unas simples reglas, salió esto:

Evolución de /r/place

Cada píxel que ves fue colocado a mano. Cada icono, cada bandera, cada meme creado minuciosamente por más de un millón de personas.

Cuando descubrí Place, ya estaba a punto de terminar. Un magnífico post de sudoscript cuenta su historia al completo.

El experimento empezó sin ningún aviso, y los usuarios empezaron a poner píxeles de cualquier manera, sólo para ver qué podían hacer. En unos minutos, los primeros dibujos aparecieron en Place. Eran bastante básicos:

Primer retrato creado en /r/Place

Pero trabajando solos, sólo podían poner un píxel cada 5 minutos. Hacer algo complejo hubiera llevado demasiado tiempo, y a alguien se le ocurrió la idea de utilizar una rejilla para hacer un dibujo colaborativo, un inocente Dickbutt.

A partir de aquí la comunidad empezó a coordinarse para hacer cosas bastante más complejas, y los dibujos empezaron a aparecer rápidamente:

Los inicios de Place

Durante los siguientes 3 días se fueron creando distintas facciones, equipos con objetivos concretos, guerras por el dominio del lienzo, coordinación entre distintos proyectos...

The Void atacando la bandera de EEUU

Por ejemplo, un grupo venido de 4chan que se hacía llamar The Void, intentó llenar el mapa de píxeles negros.

Os dejo aquí la imagen final. Si hacéis click sobre ella os llevará a un atlas que explica el significado de cada parte de la obra:

El final de Place

No hay comentarios

OpenSeaDragon: el visualizador de imágenes grandes

Alguna vez has abierto una imagen grande como esta y no has podido verla cómodamente por culpa del zoom?.

A Ian Gilman se le ha ocurrido una solución. Con OpenSeaDragon, puedes convertir una imagen grande en un mapa al que hacer zoom poco a poco con la rueda del ratón. Haz click en la imagen para ver el resultado:

Antes de OpenSeaDragonizar

El código fuente está disponible públicamente y permite incrustar la herramienta en una página web.

No hay comentarios

El cifrado XOR

Hace algún tiempo, se me ocurrió el siguiente problema:

Diseñar un cifrado recíproco con contraseña, en el que la función para encriptar y desencriptar sea la misma.

El resultado está aquí. Sigue leyendo si quieres saber cómo funciona.

Cifrado ROT-13

Los cifrados recíprocos existen desde hace mucho. Un buen ejemplo es el Cifrado ROT-13, que consiste en coger una letra del alfabeto, y rotarla 13 posiciones. Como el alfabeto (sin ñ) tiene 26 posiciones, si realizamos esta operación dos veces volvemos a la letra anterior: A -> N y N -> A.

Dial de cifrado ROT13

Cifrado XOR

Mi intención es disponer de un cifrado algo más seguro, que necesite una contraseña para encriptar/desencriptar. Y ahí es donde entra en juego el Cifrado XOR. Se basa en la operación lógica XOR (⊕), eXclusive OR:

ABA⊕B
000
011
101
110

Podemos realizar esta operación con un número si se la aplicamos a cada uno de sus bits. Por ejemplo, 220 ⊕ 153 = 69.

La magia del operador XOR es su reciprocidad: del mismo modo que 220 ⊕ 153 = 69, podemos observar que 220 ⊕ 69 = 153. Dado cualquier número A, la operación A ⊕ P = B y B ⊕ P = A. De este modo, podemos definir una contraseña P, que nos permita encriptar de forma reversible cualquier cadena, asignando un número a cada letra.

Así, si nuestra cadena es "HOLA MUNDO", nuestra constraseña es "CONTRASEÑA", y asignamos a cada letra la posición que ocupa en el abecedario reservando el 0 para el espacio; obtendremos la cadena encriptada "K BSRLBKKP".

Aplicando la operación de nuevo, con la contraseña "CONTRASEÑA" y la cadena "K BSRLBKKP", obtendríamos nuestra cadena tal y como queremos. Sin embargo, seguimos teniendo dos problemas:

Cadenas de distinta longitud

Una solución bastante simple es rellenar la contraseña con espacios hasta que tenga la longitud del texto. Sin embargo, esto no cambiaría nada, ya que A ⊕ 0 = A. Por ejemplo, con el texto "HOLA MUNDO ESTO ES UNA PRUEBA", la cadena que obtenemos es "K BSRLBKKP ESTO ES UNA PRUEBA".

Otra opción es rellenar la contraseña con algún símbolo que no sea un espacio. O para que sea menos predecible, repetir la contraseña en bucle. De este modo, para el texto anterior, usamos como contraseña "CONTRASEÑACONTRASEÑ", y el resultado de la encriptación es "K BSRLBKKPCTY CAPPÑ".

Gráfico de barras de la frecuencia (%) de las letras en castellano

Sin embargo, esta solución tampoco es segura, ya que al encriptar textos largos, sería fácil ver combinaciones de letras que se repiten mucho, y adivinar la contraseña mediante análisis de frecuencia. Pero todavía nos queda un recurso.

Funciones de hash

En criptografía, las funciones de hash son técnicas que permiten encriptar una cadena con un bajo coste, pero un coste altísimo de desencriptación, en ocasiones de milenios.

Este es el caso de la función SHA-256. Mediante esta función, podemos encriptar la contraseña y usarla para aplicar el cifrado XOR de forma segura. Para tener una contraseña más larga, tendremos una lista de salts que aplicaremos a la contraseña. No voy a entrar en detalle en esto último para que no quede un post demasiado largo, pero si tenéis interés podéis preguntar más en los comentarios.

Conclusiones

Después de todo esto hemos conseguido un cifrado recíproco medianamente seguro, y sobre todo, aprender un poco sobre criptografía.

Si lo deseas, puedes probar tú mismo este cifrado en esta página. Es una versión a la que he añadido un mayor número de caracteres.

1 comentario

¿Qué hace feliz a la gente?

Cada uno o dos años, la UNSDSN, una organización nacida de las Naciones Unidas, publica el Informe mundial de Felicidad. Este informe es el resultado de encuestar a personas de cada país para saber cómo de felices son e intentar relacionar los resultados con varios factores.

Estos factores son:

Los resultados del ranking informe de 2016 son los siguientes:

Ranking de felicidad por país

La labor de encuesta de esta organización es impresionante, encuestar a muestras significativas de 157 países distintos no es tarea fácil. Además, en su web están disponibles todos los datos del informe.

Sería interesante estudiar el impacto de algunos factores más sobre la felicidad, como la tasa de asesinatos y suicidios, horas medias de sol anuales, porcentaje de la población religioso o crecimiento económico.

Muchos estudios intentan identificar relaciones entre algo tan ambiguo y subjetivo como la felicidad y ciertos factores:

No hay comentarios

< RecientesAntiguas >