jueves, 23 de junio de 2016

CPU-Grabbers: La proxima amenaza en Internet. Codificar MP3 y enviarlo de vuelta en background con javascript

Descarga prototipo aquí.
Virus, ventanas emergentes,... Hay muchos elementos en la web que nos dificultan la navegación. Pero ¿Que es lo siguiente que aparecerá?

Tecnologias como asm.js que permiten ejecutar javascript a velocidad casi nativa, o a compiladores como Emscripten que permiten compilar javascript a partir de codigo C o C++, javascript se esta convirtiendo en el lenguaje de programación multiplataforma del futuro.

Y aqui es cuando yo planteo un concepto... ¿Y si utilizamos la potencia de javascript en nuestra pagina web para que los usuarios que accedan nos realicen tareas computacionales complejas mientras visualizan con normalidad la pagina y conforme los calculan nos lo vayan enviando de forma transparente?

Esta idea que planteo nos evitaría el costo que tendría por ejemplo el uso de super-computadores, a la vez que al usuario le aumenta el uso de CPU y por lo tanto el consumo de energía de su dispositivo.

¿Os imaginais a paginas web con millones de usuarios como Google, Twitter,... Poniendo en practica esta idea para desencriptar claves AES por fuerza bruta en muy poco tiempo?

Mi prototipo:
Aunque descifrar claves sea probablemente uno de las mayores utilidades de mi concepto de CPU-Grabber, en mi prototipo vamos a un caso mucho mas basico: Codificar de PCM a MP3.
Para ello utilizo la librería liblame.js obtenida desde github. Esta no esta optimizada para javascript, pero para un simple prototipo nos sobra.
En el prototipo teneis adjunto el servidor http "miniweb" junto a la libreria libLame.js y el resto de archivos del prototipo, incluyendo un "index.html"

Accediendo al contenido de este servidor web desde por ejemplo, un ordenador o un Iphone sin jailbreak, el dispositivo descarga audios WAV aleatorios de la carpeta "wav" que no se haya codificado aun (Comprobandolo previamente), lo codificará en MP3, y una vez hecho esto, enviará el MP3 resultante al servidor con un POST el cual nos colocara en la carpeta "mp3". Una vez hecho esto, volveremos a coger otro audio aleatorio que no se haya codificado aun, así hasta que cerremos el navegador, o no queden archivos sin codificar en nuestro servidor.

El motivo por el que se selecciona un audio aleatorio, es porque perfectamente podemos tener varios dispositivos conectados a nuestra web a la vez, cada uno codificando audios distintos simultaneamente.

Notas del prototipo:

-Hay dos modos accesibles desde index.html. El modo debug que muestra en todo momento lo que hace el javascript, y el modo poison que muestra una pagina web (politica de privacidad de ask.fm) infectada con poison.js y por lo tanto ¡codificando para nosotros MP3 sin que el usuario se entere!

-En las capturas muestro el tiempo que tardan distintos dispositivos en codificar audios (Distintos a los audios adjuntos) en el modo debug

-Acordaos que podeis insertar vuestros propios archivos "wav". Debeis establecer en index.html o poison.js (depende la demo que esteis usando) el numero de pista mas pequeño y el mas grande de vuestros archivos wav.

miércoles, 15 de junio de 2016

Primera IA que juega a "Blokus"

Descarga aquí. (Código incluido y comentado)
Blokus es un juego de mesa que me regalaron cuando era niño :')
El objetivo del juego es conseguir colocar mas cuadraditos en el tablero que tu adversario. Para ello debes colocar las fichas tipo pentomino de forma que tus fichas estén conectadas por las esquinas sin llegar a tocarse nunca.

Acordándome por casualidad decidí buscar en internet algún sitio donde jugar contra el ordenador a este juego, y mi sorpresa fue que no había ninguno. Lo que si que encontré son sitios que hay (o habían) donde se podía jugar online. En la imagen muestro un juego de PS3 para jugar únicamente online a Blokus.

Y entonces pensé... ¿Tan difícil debe ser crear una IA que juegue a este juego?
Así que me puse a crear una versión Javascript del juego para intentarlo :')

Creando la IA:
Al principio tenia en mente crear una función heurística y usar minimax, pero al final viendo que minimax sería bastante impreciso y desperdiciaría bastante tiempo de computación, vi que usando esta misma heurística de forma voraz, la IA podia generar movimientos muy buenos (Sin ser invencible, lo cual creo es bastante importante) y lo mas importante de todo... ¡Sería muy, muy rápido!
¡Y he aquí el resultado! A pesar de estar hecho en javascript, la IA no tarda ni 0.1 segundos en pensar en mi ordenador. Y va rápido incluso en mi antiguo Iphone 4.

La heurística funciona teniendo en cuenta tres parámetros:

-Expansión en el tablero --> x1
-Incrementar el numero de movimientos posibles --> x1
-P*tear al adversario :') --> x10

Esto quiere decir que la IA le da la misma importancia a expandirse en el tablero que a incrementar su numero de movimientos, y ademas tiene especial interés en que perdamos :')
Lo mejor de todo es que estos tres parámetros se pueden redefinir. Ej: podemos modificarlo de forma que el adversario quiera expandirse "Sin hacernos daño" lo cual seria un poco raro en un jugador real. Solo habría que cambiar el valor de los parámetros.
¿Que os ha parecido?

Aleatoriedad en Flappy Bird. ¿Como se si tengo el juego original?

En este mini-post os voy a contar una curiosidad sobre el mítico juego de Flappy Bird (para variar).
Como sabeis, este juego se basa en la aleatoriedad. En los dispositivos, ya sea un ordenador, tablet, u otro aparato, la aleatoriedad se consigue mediante una semilla que suele obtenerse mediante el PID (Identificador de proceso) o con el reloj.
Así, el color que tendrá Flappy al empezar y el color del cielo será totalmente aleatorio.

Pero... ¿Y las tuberias? No se muy bien si sera de forma intencionada o no, pero la disposición de las tuberias tiene la aleatoriedad basada en una semilla fija. Por ello, cada vez que inicieis el juego independientemente del dispositivo que tengais, e incuso la versión de flappy bird que tengais (siempre que sea original) el "mapa" tendra la siguiente disposición:

Haced click para darle zoom, no seais vagos :')

Y aqui no acaba la cosa. ¿Que ocurre cuando nos chocamos y empezamos de nuevo? Cuando esto ocurre la semilla cambia, siempre de la misma forma (tal vez se incremente en 1 o algo similar).
¿Cuales son las consecuencias de eso? Cuando nos choquemos por primera vez apareceremos en un "mapa" distinto, y ademas empezaremos en una posición respectiva a donde nos hemos chocado. Lo entenderéis con un ejemplo.

Las siguientes imágenes muestran:

-la segunda tubería tras haber chocado una vez en la segunda tubería de la ronda anterior.

-la tercera tubería tras haber chocado una vez en la primera tubería de la ronda anterior

Como habreis observado ¡estamos en el mismo lugar! y si siguiesemos las partidas veriamos que las tuberias seguirian estando a la misma altura, aunque en una de ellas tendremos un punto mas que en la otra.

¿Que os ha parecido? Recordad que una forma sencilla de averiguar si vuestro juego de Flappy bird es el original, es comparando el mapa del inicio con el de la primera imagen.

jueves, 9 de junio de 2016

Como adjuntar (enviar) archivos de cualquier tipo en Ask.fm -> File2PNG

Como sabeis en Ask.fm se pueden adjuntar fotos, GIFs y video-respuestas...
Pero que pasa si quereis compartir con el mundo vuestra cancion mp3 favorita, vuestro ROM favorito, vuestro documento de Word en el que estais trabajando...?
No se podia... hasta ahora :'))) Producto de mi aburrimiento he creado un shell-script para windows que convierte con ffmpeg un archivo ZIP (Aunque tambien valdria RAR y 7Z) en una imagen PNG que podeis subir a ask.fm, para mas tarde poder decodificarla de nuevo.
igual que digo ask.fm también valdria cualquier otro sitio que permita subir imagenes PNG sin perdida.

¿Como funciona? Lo primero que teneis que hacer es descargar ffmpeg si no lo teneis aun, y Crear los siguientes archivos *.bat

"ARRASTRE ZIP AQUI.bat"

@echo off
set /a pixeles= %~z1% / 3
set c=0
:raiz
set /a c= %c%+1
set /a x= %c%*%c%
if %x% LSS %pixeles% goto raiz
echo resolucion %c% x %c%
set /a nbytes= %c% * %c% * 3
set /a nulls= %nbytes% - %~z1%
copy %1% temp.rar
:bucle
if /I %nulls% LEQ 0 (goto ffmpeg)
echo "juanmv94" >> temp.rar
set /a nulls=%nulls%-13
goto bucle
:ffmpeg
ffmpeg -f rawvideo -s %c%x%c% -pix_fmt rgb24 -i temp.rar salida.png
del temp.rar


"ARRASTRE PNG AQUI.bat"
@echo off

ffmpeg -i %1% -f rawvideo -pix_fmt rgb24 salida.zip

El nombre de los archivos son autodescriptivos. Para codificar se arrastra el zip al primer script, y para decodificar se arrastra el archivo PNG al segundo.

Detalles tecnicos:
El script convierte un archivo binario a un mapa de bits de rgb de 24 bits que se codificará en PNG.
Lo primero que hace el script al codificar es calcular las dimensiones que tendrá la imagen calculando la raiz cuadrada. Los pixeles sobrantes del cuadrado mas pequeño que contenga el archivo se rellenaran con la etiqueta en texto plano "juanmv94" la cual se repetira hasta llenar el cuadrado.

Para decodificar simplemente convertimos el archivo PNG a mapa de bits y extraemos el contenido RAW al archivo ZIP en este caso.