miércoles, 28 de julio de 2010

Una ronda de bash ( y II )

[La primera parte] (La división va porque se hace incómodo editar el HTML para meter los spoilers con posts largos... si, lo se, soy un vago)

Nota: por alguna razón no se muestran los spoilers si se ven desde la portada, entrad en el post y debería ir.

Los siguientes códigos usan /proc/acpi/ para mostrar la temperatura y Zenity o KDialog para mostrarlo por una GUI

El primero es la base, muestra simplemente las temperaturas por pantalla [temp.sh]:


./temp.sh [-c]

El -c para que también se muestre el símbolo de la medida (¿grados?)


#!/bin/bash
# Escrito por kenkeiras
back=$PWD
cd /proc/acpi/thermal_zone/
if [ "$1" = "-c" ]; then
    lonx=4
else
    lonx=3
fi

for i in *; do
    e=`cat $i/temperature`
    e=${e:`expr length "$e"`-4:$lonx}
    echo "$i: $e"
done

cd $back


Este es con Zenity, es decir, con Gtk [ztemp.sh]


./ztemp.sh




#!/bin/bash
# Escrito por kenkeiras
back=$PWD
cd /proc/acpi/thermal_zone/
tmpList=""
for i in *; do
    e=`cat $i/temperature`
    e=${e:`expr length "$e"`-4:3}
    tmpList="$tmpList $i $e"
done
cd $back
zenity --list --text "" --title "ZenTemp" \
--column "Dispositivo" --column "Temperatura" $tmpList



Visto esto ya no parece tan dificil programar GUI's ^^

Y con KDialog (Qt/Kde) [ktemp.sh]:


./ktemp.sh




#!/bin/bash
# Escrito por kenkeiras
back=$PWD
dump=kdetempdump
cd /proc/acpi/thermal_zone/
tmpVar=""
for i in *; do
    e=`cat $i/temperature`
    e=${e:`expr length "$e"`-4:3}
    tmpVar=$tmpVar"$i: $e\n"
done
cd $back
echo -en $tmpVar > $dump
kdialog --title "KdeTemp" --textbox $dump
rm -f $dump



Y eso es todo, hasta otra

ps: De nuevo todo bajo la WTFPL, claro

Una ronda de bash ( I )

Hoy... scripts varios en bash.

Empezando por lo más simple, un cracker de MD5, simplemente lee el diccionario y va comparando las lineas con el hash objetivo [md5crack.sh]


./md5crack.sh <diccionario> <objetivo>




#!/usr/bin/env bash
# Escrito por kenkeiras
function showuse {
    echo "$0 <diccionario> <hash>"
    exit 1
}

if [ "$1" = "" ]
then
    showuse
fi

if [ "$2" = "" ]
then
    showuse
fi

i=0
for word in $(cat $1);do
    test=`echo -en "$word" |md5sum|cut -c1-32`
    if [ "$test" = "$2" ]
        then
            echo "-> $word"
            i=$(($i + 1))
        fi
done
echo "$i resultados"


Siguiendo con pruebas de /dev/tcp, buscar las contraseñas por defecto usando la web del cirt [get_pass_cirt.sh]:


./get_pass_cirt.sh <Criterio de búsqueda>



#!/usr/bin/env bash
# Escrito por kenkeiras

if [ "$1" = "" ]; then
    echo "No has especificado un criterio de búsqueda"
    exit 1
else
    key=$1
fi

# Se pide la web
exec 3<>/dev/tcp/cirt.net/80
echo -en "GET /passwords?criteria=$key\ HTTP/1.1\r\n" >&3
echo -en "HOST: cirt.net\r\n" >&3
echo -en "Connection: close\r\n\r\n" >&3
res=$(cat <&3) # Se leen los datos
exec 3>&- # Se cierra la conexion

n=0
for i in $res
    do
        if [ $n -eq 1 ] # Se comprueba si ya muestra el usuario/contraseña
            then
                echo $i|cut -d\> -f2|cut -d\< -f1
                n=0
        else if [ $n -ne 0 ] # Sino puede que venga pronto
            then
                n=$(($n - 1))
            fi
        fi
        out=$(echo $i|grep -e User -e \>Pass)
        if [ $? -eq 0 ] # Si es la parte del usuario/contraseña
            then
                out=$(echo $out|cut -d\> -f3|cut -d\& -f1|cut -d\< -f1)
                if [ ! $out = "" ]
                    then
                        echo $out|grep Pass >> /dev/null
                        if [ $? -eq 0 ]
                            then
                                n=2
                            else
                                n=3
                            fi
                        echo -n "$out:"
                    fi
            else
                echo $i|grep -e "</table>" >> /dev/null # Si se acabo el user/pass
                if [ $? -eq 0 ]
                    then
                        echo "----------------------------"
                    fi
            fi
    done


O usando la web de phenoelit [get_pass_phenoelit-us.sh] este tarda un rato, tiene que parsear 256 Kb's:

./get_pass_phenoelit-us.sh  <Empresa>



#!/usr/bin/env bash
# Escrito por kenkeiras

if [ "$1" = "" ]; then
    echo "No has especificado un criterio de búsqueda"
    exit 1
else
    key=$1
fi

# Se pide la web
exec 3<>/dev/tcp/www.phenoelit-us.org/80
echo -en "GET /dpl/dpl.html HTTP/1.1\r\n" >&3
echo -en "HOST: www.phenoelit-us.org\r\n" >&3
echo -en "Connection: close\r\n\r\n" >&3
res=$(cat <&3) # Se leen los datosexec 3>&- # Se cierra la conexion
res=$(echo $res|sed -e "s/\n//g" |sed -e "s/ /$/g" |sed -e "s/[<]/\n/g")

t=0
d=0
for i in $res
    do  
        echo $i|grep "/tr" >> /dev/null
        if [ $? -eq 0 ]
            then
                if [ $t -ne 0 ]
                    then
                        echo "------------------"
                    fi
                d=1
                t=0
            else
                echo $i|grep "</table>" >> /dev/null
                if [ $? -eq 0 ]
                    then
                        d=0
                    fi
                if [ $d -ne 0 ]
                    then
                        d=$(($d + 1))
                        if [ $d = 3 ]
                            then
                                out=$(echo $i|cut -d\> -f2|grep -i "$key")
                                if [ $? -eq 0 ]
                                    then
                                        echo $out|sed -e "s/$/ /g"
                                        t=1
                                    fi
                            fi
                        if [ $t -ne 0 ]
                            then
                                if [ $d = 11 ]
                                    then
                                        echo -n "User: "
                                        echo $i|cut -d\> -f2|sed -e "s/$/ /g"
                                    else
                                    if [ $d = 13 ]
                                        then
                                            echo -n "Password: "
                                            echo $i|cut -d\> -f2|sed -e "s/$º/ /g"
                                        fi
                                    fi
                            fi
                    fi
            fi
    done


Hasta ahora, la segunda parte por la tarde

ps: Todo bajo la WTFPL, claro

martes, 27 de julio de 2010

Hablando en esotérico

Hoy traigo un script que programa en lenguajes esotéricos, concretamente en Brainfuck, Ook!, Whitespace y Zombie.

Lo único que hace es escribir un programa que muestre por pantalla lo que el usuario pida, su uso es:


./esoprint.py [-h]  [-l <lenguaje>] [-o <archivo de salida>] [<datos> [<datos> | -n [...] ] | -n]
-h (--help): muestra esta "ayuda"
-l (--language): Selecciona el lenguaje
-o (--output) : Selecciona el archivo de salida (a stdout por defecto)
El resto se toma como información, el -n (--newline) es considerado un salto de línea



El script se puede descargar [aquí] o al final coloreado

Dejando a parte de Brainfuck y Ook!, de los que se habló antes, Whitespace es un lenguaje compuesto únicamente por espacios, tabuladores y saltos de línea, con un conjunto de instrucciones bastante completo [Whitespace Tutorial] . Zombie está por estar, ni siquiera encontré un intérprete así que no puedo asegurar que funcione, simplemente parecía fácil de programar :).

Y eso es todo.

Tengo que dejar la manía de poner los comentarios en inglés :S ...

[Referencias]
http://compsoc.dur.ac.uk/whitespace/
http://esoteric.voxelperfect.net/wiki/Main_Page



#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
   esoprint.py, encodes in esoteric language code

   Supported languages:
   - Brainfuck
   - Ook!
   - Whitespace
   - Zombie # Blindly coded, not tested

   Maybe future supported languages:
   - Tink
   - Piet
   - Befunge
   - False
   - Q-BAL # When I find a interpreter
   - Malbolge # Maybe too big...
   - Beatnik # Really ¿?
   - Unlambda

   Not future supported languages:
   # It's not a logical thing to make a computer generate this!
   - Sheakspere
   - Haiku
   - Chef
   # Make's it boring
   - Whenever
   # Impossible
   - HQ9+
   - BIT

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   Copyright (C) 2010 kenkeiras <kenkeiras@gmail.com>

            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
                    Version 2, December 2004

Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>

Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.

            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

  0. You just DO WHAT THE FUCK YOU WANT TO.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Usage:

./esoprint.py [-h]  [-l <language>] [-o <output file>] [<data> [<data> | -n [...] ] | -n]
-h (--help): prints this help
-l (--language): Set's output language, currently supported: Ook!, Brainf*ck, Whitespace, Zombie
-o (--output) : Set's output file (to stdout by default)
Whatever else is considered as data, the -n (--newline) is considered a line jump

"""

# Language dictionary elements for BrainFuck-like langs
# init: program initalization
# inc
# dec
# push
# pop
# show
# # get [Actually unused]

def usage():
    import sys

    print sys.argv[0]+" [-h]  [-l <language>] [-o <output file>] [<data> [<data> | -n [...] ] | -n] "
    print "-h (--help): prints this help"
    print "-l (--language): Set's output language"
    print "-o (--output) : Set's output file (to stdout by default)"
    print "Whatever else is considered as data, the -n (--newline) is considered a line jump"
    print "If no data is entered, it will be received from STDIN"
    print "Supported languages:"
    print """   - Brainfuck
   - Ook!
   - Whitespace
   - Zombie
"""

brainfuck = {
    "init": "",
    "inc":"+",
    "dec":"-",
    "push":">",
    "pop":"<",
    "show":".",
    "get":",",    #Unused
    "loop":"[",  # Unused
    "endloop":"]" # Unused
}

ook = {
    "init": "",
    "inc":"Ook. Ook. ",
    "dec":"Ook! Ook! ",
    "push":"Ook. Ook? ",
    "pop":"Ook? Ook. ",
    "show":"Ook! Ook. ",
    "get":"Ook. Ook! ",    # Unused
    "loop":"Ook! Ook? ",  # Unused
    "endloop":"Ook? Ook! " # Unused
}

# Encodes in a Zombie program
def zombie_encode(data):

    z = "Dundun is a zombie\n"
    z += "    summon\n"
    z += "    task talk\n"
    for p in data.split("\n"):
        z += "        say \""+str( p.replace("\"","\\\"") )+"\"\n"
    z += "    animate\n"
    z += "animate"
    return z

# Encodes in a Whitespace program
def whitespace_encode(data):
    for c in data:
        w += "  " # Push into the stack: [Space] [Space]
        w += " " # Element, always positive [Space]
        # Character to binary (needed)
        b = bin( ord( c ) )
        w += b[ 2 : ].replace("0"," ").replace("1","\t") #   Space: 0 || Tab: 1
        w += "\n" # Element end: [LF]
        w += "\t\n  " # Output stack top: [Tab][LF][Space][Space]

    w += "\n\n\n" # Ending [LF][LF]
    return w

# Encodes in a Brainf*ck-like language
def stack_encode(lang, data):
    s = lang['init']
    n = 0
    for c in data:
        i = ord( c )
        while ( n > i ):
            s += lang['dec']
            n -= 1

        while ( n < i ):
            s += lang['inc']
            n += 1

        s += lang['show']

    return s

bf_like = {"brainfuck":brainfuck,"ook":ook}
langlist = {"whitespace":whitespace_encode,"zombie":zombie_encode}
if __name__ == "__main__":

    import sys
    argc=len(sys.argv)
    lang=""
    data=""
    out = ""
    i=1
    while (i < argc):
        if (sys.argv[i] == "-l") or (sys.argv[i] == "--language"):
            i += 1
            lang = sys.argv[i]

        elif (sys.argv[i] == "-o") or (sys.argv[i] == "--output"):
            i += 1
            out = sys.argv[i]

        elif (sys.argv[i] == "-h") or (sys.argv[i] == "--help"):
            usage()
            sys.exit(0)

        elif (sys.argv[i] == "-n") or (sys.argv[i] == "--newline"):
            data += "\n"

        else:
            data = (data+" "+sys.argv[i]).strip()

        i+=1
    if (lang == ""):
        lang = raw_input("Select language: ")

    lang = lang.lower()
    if (lang not in langlist) and (lang not in bf_like):

        print "Unknown language (lenguaje desconocido)"
        sys.exit(1)

    if (data == ""):
        for line in sys.stdin:
            data += line

    if (data == "\n"):
        print "Sin entrada, saliendo..."

        sys.exit(0)

    if (lang in langlist):
        result = langlist[lang](data)
    else:
        result = stack_encode(bf_like[lang],data)

    if (out == ""):
        print result

    else:
        f = open(out,"w")
        f.write(result)
        f.close()

Fallos en Deviantshare

Resulta que ultimamente (¿ayer?) el blog estuvo redirigiendo a deviantshare.com por problemas con el "gadget", resulta que parece que la página ya no existe, de ahí todo el lío.

Y eso es todo, perdón por las molestias.

viernes, 23 de julio de 2010

Introducción a Structure Synth ( y II )

Bien, seguimos con Structure Synth...

Definición de nuevas reglas

Recordemos que la unidad básica de los scripts de Structure Synth son las reglas (y las reglas más básicas las primitivas), así que existe la posibilidad de definir nuestras propias reglas, esto se hace sencillamente haciendo:


rule <nombre de la regla> {
componentes de la regla
}


Es decir, para hacer una figura similar a una casa (hay que echarle algo de imaginación),se podria hacer

Box
{ x 0.5 ry 45 s 0.75 } Box




Si se utilizase esta forma varias veces, se podria definir una regla que la construyese directamente:


rule casa{
    Box
    { x 0.5 ry 45 s 0.75 } Box
}


Aleatoriedad

Además, si se define una misma regla varias veces, se escojera una aleatoria entre las definidas, por ejemplo, si definimos


rule micaja{
    { color blue } Box
}

rule micaja {
    { color red } Box
}



Cada vez que llamemos a micaja, obtendremos una caja de color azul o rojo, escogida al azar, por ejemplo:


10 * { x 1 } 10 * { y 1 } micaja


Se puede cambiar la probabilidad de que salga una regla cualquiera simplemente haciendo


rule <nombre de la regla> weigth <probabilidad de la regla> {
componentes de la regla
}


La probabilidad por defecto es 1, si es 2, hay el doble de posibilidades, con 0.5, la mitad...

Recursividad

Por supuesto, una regla puede llamarse a si misma (recursividad), en estos casos hay que tener en cuenta el parámetro maxdepth (set maxdepth <valor>) que especifica la profundidad máxima que puede alcanzar la recursión.
La recursividad no requiere ningun truco, simplemente se llama a la propia regla como se llamaría a cualquier otra, por ejemplo, si recordamos el código de la espiral:


360 * { ry 1 x 1 s 0.995 } Box


Este se puede pasar a recursivo simplemente llamando a la figura base ( aquí Box ) y aplicando las transformaciones a la siguiente recursión:

rule espiral{
    Box
    { ry 1 x 1 s 0.995 } espiral
}

espiral  // Hace falta iniciar el proceso

El resultado es bastante similar, con la diferencia de que no se define un límite, sino que este depende de los parámetros.

Transformaciones geométricas: cambios de tamaño "avanzado"

Hasta ahora para cambiar el tamaño del sistema de coordenadas, lo hemos hecho con todas las dimensiones a la vez, es decir, 'X', 'Y' y 'Z' crecían en la misma proporción, con lo que, por ejemplo, un cubo (Box) era siempre un cubo perfecto, pero se puede cambiar el tamaño de las dimensiones de forma independiente, la transformación entonces es esta:
s <nueva proporción de X> <nueva proporción de Y> <nueva proporción de Z> 

Esto puede parecer un lío al principio, es solo cosa de cojerle el truco, por ejemplo, si queremos una caja (Box) con 0.1 de ancho, 1 de alto, y un 1 de lado haríamos:


{ s 0.1 1 1 } Box


O, si queremos uno con 0.1 de ancho, 2 de alto, y un 0.1 de lado

{ s 0.1 2 0.1 } Box


Estas figuras pueden ser interesantes para simular líneas, que suelen tener problemas al pasarse por Sunflow, por ejemplo, para hacer un toro con ellas:

180 * { ry 2 x 0.5 hue 2 } 72 * { rx 5 rz 5 y 1 } basefig

rule basefig{
    { s 1 0.1 0.1 } box
}


Fractales
Como con logo, los fractales no pueden faltar, copio y pego la "introducción":
Un fractal es un objeto semigeométrico cuya estructura básica, fragmentada o irregular, se repite a diferentes escalas.[1] Una mejor manera para comprender el comportamiento fractal de nuestro universo es considerar la siguiente definición: "Patrones que se repiten a distintas escalas".
A un objeto geométrico fractal se le atribuyen las siguientes características:[2]
Dejemos aparte todo lo de "autosimilar", "dimensiones topologicas" y demas... lo mas comprensible es que "se repite a distintas escalas" y "se define mediante un simple algoritmo recursivo", vamos a probar...

Supongamos que queremos hacer un fractal similar a una alfombra de Sierpinski, los pasos para hacerlo son:
  1. Poner un cuadrado en el centro
  2. Repetir el proceso a menor escala en los lados y diagonales del cuadrado

Perfectamente recursivo, ¿verdad?, además no requiere ninguna herramienta que no proporcione Structure Synth y se aplicar sencillamente a 3D:

  1. Poner un cubo en el centro
  2. Repetir el proceso a menor escala en los lados y diagonales del cubo

El código, que nadie se asuste que el tocho es para que se repita en cada lado, es solo copiar-pegar cambiando las distancias en 'X', 'Y' y 'Z' y  el hue es para que la imágen quede más clara, con diferente color para cada nivel de recursi:


set background white
set maxdepth 5  // Profundidad máxima
#define space 3   // Espaciado entre figuras
#define ratio 0.33  // Ratio de cambio de tamaño
#define color_change 50  // Tamaño de los pasos de cambio de color

sierpinski

rule sierpinski{
    { hue color_change s ratio x space  } sierpinski
    { hue color_change s ratio x -space } sierpinski

    { hue color_change s ratio y space   } sierpinski
    { hue color_change s ratio y -space  } sierpinski

    { hue color_change s ratio z space   } sierpinski
    { hue color_change s ratio z -space  } sierpinski

    { hue color_change s ratio x space y space                 } sierpinski
    { hue color_change s ratio x space y space  z space   } sierpinski
    { hue color_change s ratio x space y space  z -space  } sierpinski
    { hue color_change s ratio x space y -space                } sierpinski
    { hue color_change s ratio x space y -space  z space  } sierpinski
    { hue color_change s ratio x space y -space  z -space } sierpinski

    { hue color_change s ratio x -space y space                 } sierpinski
    { hue color_change s ratio x -space y space  z space   } sierpinski
    { hue color_change s ratio x -space y space  z -space  } sierpinski
    { hue color_change s ratio x -space y -space                } sierpinski
    { hue color_change s ratio x -space y -space  z space  } sierpinski
    { hue color_change s ratio x -space y -space  z -space } sierpinski

    { hue color_change s ratio y space  z space   } sierpinski
    { hue color_change s ratio y space  z -space  } sierpinski
    { hue color_change s ratio y -space  z space  } sierpinski
    { hue color_change s ratio y -space  z -space } sierpinski

    { hue color_change s ratio z space  x space  } sierpinski
    { hue color_change s ratio z space  x -space } sierpinski
    { hue color_change s ratio z -space x space  } sierpinski
    { hue color_change s ratio z -space x -space } sierpinski

    box
}



Pasando a algo más complicado, un triángulo de Sierpinski, extrapolado a 3D (ya se mostró el código para 2D), el proceso sería este:
  1. Se dibuja un triangulo (la estructura externa)
  2. Se repite el proceso a la mitad de escala en la mitad de cada diagonal

Y esto fue lo mejor que conseguí, sobre todo lo que no me gusta son tantos números que no son "redondos" :(

#define thick 0.05
#define linecolor red
#define basecolor white
set maxdepth 20

triangulo

rule triangulo {

    // Diagonales
    { color linecolor  x -0.5  y 0.75 z -0.5 rx 181.7 ry 45 rz 45  s 2.1 thick thick } box
    { color linecolor  x -0.5  y -0.75 z 0.5 rx 1.7 ry 45 rz 45  s 2.1 thick thick } box
    { color linecolor  x -0.5  y -0.5 z -0.75 rx 91.7 ry 45 rz 45  s 2.1 thick thick } box
    { color linecolor  x -0.5  y 0.5 z 0.75 rx 271.7 ry 45 rz 45  s 2.1 thick thick } box

    // Base
    { color basecolor  x -1.025 rx 11  s 0.05 2.6 2.6} box  

    // Niveles interiores

    {  s 0.5 } triangulo

    { x -0.5  y 0.73 z -0.495 s 0.5 } triangulo
    { x -0.5  y -0.73 z 0.495  s 0.5 } triangulo
    { x -0.5  y -0.495 z -0.73  s 0.5 } triangulo
    { x -0.5  y 0.495 z 0.73 s 0.5 } triangulo

}


Además, hablando de fractales no pueden faltar los árboles binarios, esta vez representados en 3D (código e imágen de Vishkey), muy logrado el efecto de las "ramas" al dividirse:

set background #0066CC
{s 30 0.1 30 y -5 color #330000} box
4 *{x 2} 4 * {z 2} 1 * {rz 90} r1

rule r1 maxdepth 15 {
    c1
    {s 0.5 0.5 1 x 1.4 y 0.25 rz 30 b 100} r1
    {s 0.5 0.5 1 x 1.4 y -0.25 rz -30 b 100} r1
    {s 1 0.5 0.5 z -0.25 x 0.98 ry 30 b 100} r1
    {s 1 0.5 0.5 z 0.25 x 0.98 ry -30 b 100} r1
}

rule c1 {
    {s 1 0.05 0.05 color green} box
}



Por último... no es un fractal, pero me gustó el resultado, aunque es uno diferente cada vez que se ejecuta :P

set maxdepth 500
#define color_change 0.5

spiral

rule spiral weight 100{
    box
    { s 0.999 hue color_change ry 0.5 x 1 } spiral
}

rule spiral weight 1{
    box
    { s 0.95 hue color_change rx 180 ry 1 x 1 } spiral
    { s 0.99 hue color_change ry 1 x 1 } spiral
}

rule spiral weight 0.01{
    box
    { s 0.99 hue color_change rx 180 ry 1 x 1 } spiral
}


Hasta la próxima.

[Referencias]
http://www.fractalforums.com/
http://structuresynth.sourceforge.net/
http://structuresynth.sourceforge.net/reference.php
http://sunflow.sourceforge.net/
http://www.fractovia.org/art/es/

miércoles, 21 de julio de 2010

ROT 13, Brainfuck y Ook! (+traductor)

Hoy presento uno de los desavarios mas preocupantes que he escrito últimamente, unos programas en Brainfuck (muy sencillos, eso sí)... pero empezemos por el principio.

Actualizado: el traductor ahora también soporta interpretes de Ook! que no permitan comentarios.

Brainfuck

Como dice la Wikipedia:

Brainfuck (jodecerebros), es un lenguaje de programación esotérico, diseñado por Urban Müller en 1993, con el objetivo de hacer un lenguaje que fuera a la vez muy simple, Turing completo y que requiriese un compilador pequeño. Müller basó Brainfuck en la máquina de Turing y le sirvió de inspiración el compilador de 1024 bytes de tamaño del lenguaje FALSE.
La distribución clásica es la versión 2 escrita por el propio Müller, conteniendo un compilador para el ordenador Amiga, un intérprete, programas de ejemplo y un documento "readme".

Brainfuck tiene solo 8 instrucciones:
  • >   Incrementa el puntero, en C sería p++ 
  • <   Decrementa el puntero, en C sería p--
  • + Incrementa el byte al que apunta el puntero, en C p*++
  • - Decrementa el byte al que apunta el puntero, en C p*--
  • [ Salta hasta el ], si el byte apuntado es 0, en C  while (p*){
  • ] Salta hasta el [, si el byte apuntado es distinto de 0, en C sería el } del while
  • . Muestra por pantalla el valor apuntado, en C putchar(p*);
  • , Acepta un valor por STDIN y lo guarda en el byte apuntado, p*=getchar();

El resto de caracteres se ignora, el Hola mundo, por ejemplo, sería (sacado de Wikipedia):

++++++++++
[              Bucle para iniciar las memorias (se repite 10 veces)
 >+++++++>++++++++++>+++++++++++>+++>+<<<<<-
      70        100       110      30  10
]
>++.              imprime 'H'   (72) 1
>>+.              imprime 'o'  (111) 3
---.                      'l'  (108) 3
<---.                     'a'   (97) 2
>>++.                   espacio (32) 4
<+.                       'm'  (109) 3
++++++++.                 'u'  (117) 3
-------.                  'n'  (110) 3
<+++.                     'd'  (100) 2
>+.                       'o'  (111) 3
>+.                       '!'   (33) 4
>.                   nuevalínea (10) 5

Ook!

Además, este lenguaje dio lugar a otro, llamado Ook!, un lenguaje "diseñado para orangutanes":

Ook! (con el signo de exclamación) es un lenguaje de programación esotérico Turing completo. Este lenguaje es una parodia de Brainfuck, del que toma su conjunto completo de comandos (ver tabla). Deriva su completitud Turing de esta relación.
Según su diseñador, David Morgan-Mar, el lenguaje está diseñado para orangutanes. Tiene 3 palabras reservadas (Ook., Ook?, y Ook!); que pueden combinarse en ocho maneras diferentes para formar el repertorio de instrucciones del lenguaje. Ook! pretende ser fácil de aprender para los orangutanes y evitar cualquier mención de la palabra «mono». [Wikipedia]

Comparten el set de instrucciones, cambiando solo su nombre, esta es la relación de los comandos Brainfuck - Ook!
  • > : Ook. Ook?   Incrementa el puntero, en C sería p++ 
  • < : Ook? Ook.   Decrementa el puntero, en C sería p--
  • + : Ook. Ook. Incrementa el byte al que apunta el puntero, en C p*++
  • - : Ook! Ook! Decrementa el byte al que apunta el puntero, en C p*--
  • [ : Ook! Ook? Salta hasta el ], si el byte apuntado es 0, en C  while (p*){
  • ] : Ook? Ook! Salta hasta el [, si el byte apuntado es distinto de 0, en C sería el } del while
  • . : Ook! Ook. Muestra por pantalla el valor apuntado, en C putchar(p*);
  • , : Ook. Ook! Acepta un valor por STDIN y lo guarda en el byte apuntado, p*=getchar();

ROT 13

Y por último, ROT 13, este no es un lenguaje de programación, solo un sistema clásico de cifrado de tipo césar ("movía" las letras n veces hacia la derecha) con la peculiaridad de que al mover las letras 13 veces, el cifrado y el descifrado se hacían igual.Así de simple, si quieres ver más -> https://secure.wikimedia.org/wikipedia/es/wiki/ROT13

Al tema...

Bien, el "reto" era escribir un programa en Brainfuck que cifrase con ROT-13 y otro que convirtiese un código en ese lenguaje a Ook!, para empezar, como base y para entender mejor el lenguaje, escribí un programa que guardase lo que el usuario dijera y lo devolviese despues por pantalla.

Este es el código,el caracter para detener la entrada es Enter, más que nada porque es más fácil de utilizar:

Guarda lo que dice el usuario, hasta que pulse enter
>+[>,----------]
Vuelve al principio de la cadena
+++
[<]>>
Muestra los caracteres
[++++++++++.>]
Salta a una nueva linea
++++++++++.

Por muy críptico que parezca, en realidad es bastante sencillo si se lee paso a paso:

{Línea 1}
Primero se salta a un nuevo puntero ( > ), para dejar este intacto (con valor 0), y que sirva como limitador de la cadena, después se suma 1 al valor apuntado, para poder entrar en el while.
Una vez en el while se vuelve a incrementar ( > ) el puntero, esto se hace para conseguir un byte diferente por cada letra que el usuario introduzca, en ese byte se introduce lo que usuario mande ( , ), y a este valor se le resta 10 ( ---------- ) para hacer que si es un salto de línea, que tiene el valor 10, se quede a 0, en el resto de valores se revertirá. y se acabe el bucle, por último se cierra el while ( ] ).

{Línea 2}
Se suman 3 al valor apuntado ( +++ ), este byte corresponde al Enter del usuario, se podría pensar que hay que dejarlo a 0, para que luego al sumar 10 a todo para recuperar los valores originales se muestre el enter, el problema es que no debe estar a 0, ya que sino no podremos "entrar" en el siguiente while, así que añadiendo 3, más los 10 posteriores se convierte en un retorno de carro, y no molesta por el medio.

{Línea 3}
Se vuelve al principio, haciendo while ( [ ) y retrocediendo el puntero ( < ) , hasta que finalmente se encuentre con el valor 0 que dejamos al principio, y que hará que el programa salga del bucle ( ] ), una vez ahí avanzamos 2 veces el puntero ( > ) y ( > ), uno por el valor nulo y otro por el 1 que dejamos para poder entrar en el bucle del principio.

{Línea 4}
Solo queda ir leyendo carácter a carácter con un bucle ( [ ), sumando 10 para recuperar los valores originales ( ++++++++++ ) , mostrarlos por pantalla ( . ) y saltar al siguiente carácter ( > ), el bucle acabará ( ] ) con el último carácter, que será un 0

{Línea 5}
Solo queda hacer el salto de línea que cambiamos por un retorno de carro, simplemente añadiendo 10 al valor nulo actual ( ++++++++++ )  y mostrandolo por pantalla ( . ) .

Si te parece extraño (que lo es, para que nos vamos a engañar), piensa que pinta tendría el código solo:
>+[>,----------]+++[<]>>[++++++++++.>]++++++++++.

Aunque también se podría hacer por la vía fácil:
+[,.----------]
¿Pero que gracia tendría así?

"Cifrando" y "descifrando" (con ROT 13)

Por cosas de la vida, no se pueden aprovechar las facilidades del ROT 13, ya que la aritmética es nula, así que habrá que conformarse con hacer un par de programas, uno que añada 13 y otro que los reste, esto se puede hacer sencillamente aprovechando el programa que repite lo que dice el usuario, solo hay que añadir una parte que añada 13 antes de mostrar el valor "cifrado" y que los reste antes del "descifrado",  el añadido es obvio, lo único que merece la pena comentar es que el movimiento adicional de punteros es para evitar que queden caracteres feos por el medio con las rotariones (el 13 es invisible, pero el 26, 13+13, no siempre ) :

Cifrar:
>+[>,----------]
Vuelve al principio de la cadena
+++
[<]>>>
Imprime la info
[<++++++++++ +++++++++++++.>>]
Imprime un espacio
++++++++++.

Descifrar:
>+[>,----------]
Vuelve al principio de la cadena
+++
[<]>>>
Imprime la info
[<++++++++++ -------------.>>]
Imprime un espacio
++++++++++.

Traduciendo a Ook!

Y Ook! ... tenía escrito un traductor de Brainfuck a Ook!, pero me lo cargué :(, a ver si lo reescribo, sinó habra que conformarse con este script en python.
EDIT (00:15): al final si que hay traductor, lo conseguí reescribir de 0, y la verdad... quedé contento con el resultado, está coloreado despues de las referencias o [aquí], como detalle comentar que los datos acaban con un "\0" , así que quiza sea mejor usarlo así:


(cat loquesea.b ;echo -e "\0")|./bf2ook > loquesea.ook



ps: Pygments es sorprendente, hasta colorea esto :P

Hasta otra, si es que queda alguien cuerdo por ahí... :)

[Referencias]
http://codegolf.com/brainfuck
https://secure.wikimedia.org/wikipedia/es/wiki/Brainfuck
https://secure.wikimedia.org/wikipedia/es/wiki/Ook!




(Primero se preparan las letras)
>           (Para uso posterior) (L 1)
>>> (Esta memoria me la reservo) (L 3)
O = 79
o = 111
k = 107
! = 33
? = 63
(punto) = 46
(espacio) = 32
++++++++++ (L 4)
[
      >++++++++ ( 8 )   (L  5)
      >+++++++++++ (11) (L  6)
      >+++++++++++ (11) (L  7)
      >+++ (3)          (L  8)
      >++++++ (6)       (L  9)
      >+++++ (5)        (L 10)
      >+++ (3)          (L 11)
      <<<<<<<-          (L  4)
]
>-     (L  5)
>+     (L  6)
>---   (L  7)
>+++   (L  8)
>+++   (L  9)
>----  (L 10)
>++    (L 11)
<<<<<<< (L 4)
<<< (Se vuelve al principio) (L 1)
,   (Se lee lo que el usuario dice)  (L 1)
[
    (Se copia por si no es codigo )
    (en el nivel 2 L = 2)
    [>+>+<<-]
    >>        (L 3)
    [-<<+>>]
    <<        (L 1)
    
    (Por defecto NO es codigo)
    >>>+ (L 4)
    <<<  (L 1)
    (El L = 3 se usa para buscar los valores)
    >>++++ (L 3)
    [<<---------- (L 1) >> -] (L 3)
    <<--- (L 1)
    [   (Si no es un mas)
        - (L 1)
        [   (Si no es una coma)
            -    (L 1)
            [   (Si no es un menos)
                -  (L 1)
                [   (Si no es un punto)
                    -------------- (Menos 14) (L 1)
                    [   (Si no es un menor que)
                        -- (L 1)
                        [   ( Si no es un mayor que )
                            <++++ (L 0)
                            [->-------<] (Se resta 28)
                            >     (L 1)
                            -     (L 1)
                            [   ( Si no abre corchetes )
                                -- (L 1)
                                [   ( Si no cierra corchetes )
                                    > (Anhade un punto si permite comentarios) (L 2) (No es codigo dice el caracter a secas)
                                    >> - (L 4) ( Parece que no pero es dificil no meter )
                                    <<< (L 1)  ( codigo sin querer en los comentarios )
                                    [-] (Pone el caracter actual a 0)
                                ]
                                >>> (L 4)
                                [   ( Si cierra corchetes )
                                    >.   (L  5)
                                    >.   (L  6)
                                    >.   (L  7)
                                    >>.   (L  9)
                                    >>.   (L 11)
                                    <<<<<<< (L 4)
                                    >.   (L  5)
                                    >.   (L  6)
                                    >.   (L  7)
                                    >.   (L  8)
                                    >>>.   (L 11)
                                    <<<<<<< (L 4)
                                    - (L 4)
                                ]
                                <<< (L 1)
                            ]
                            >>> (L 4)
                            [   ( Si abre corchetes
                                >.   (L  5)
                                >.   (L  6)
                                >.   (L  7)
                                >.   (L  8)
                                >>>.   (L 11)
                                <<<<<<< (L 4)
                                >.   (L  5)
                                >.   (L  6)
                                >.   (L  7)
                                >>.   (L 9)
                                >>.   (L 11)
                                <<<<<<< (L 4)
                                - (L 4)
                            ]
                            <<< (L 1)
                        ]
                        >>> (L 4)
                        [   ( Si es un mayor que )
                            >.   (L  5)
                            >.   (L  6)
                            >.   (L  7)
                            >>>. (L 10)
                            >.   (L 11)
                            <<<<<<< (L 4)
                            >.   (L  5)
                            >.   (L  6)
                            >.   (L  7)
                           >>.   (L 9)
                           >>.   (L 11)
                           <<<<<<< (L 4)
                           - (L 4)
                        ]
                        <<< (L 1)
                    ]
                    >>> (L 4)
                    [   (Si es un menor que)
                        >.   (L  5)
                        >.   (L  6)
                        >.   (L  7)
                        >>.   (L 9)
                        >>.   (L 11)
                        <<<<<<< (L 4)
                        >.   (L  5)
                        >.   (L  6)
                        >.   (L  7)
                        >>>. (L 10)
                        >.   (L 11)
                        <<<<<<< (L 4)
                        - (L 4)
                    ]
                    <<< (L 1)
                ]
                >>> (L 4)
                [   ( Si es un punto)
                    >.   (L  5)
                    >.   (L  6)
                    >.   (L  7)
                    >.   (L  8)
                    >>>.   (L 11)
                    <<<<<<< (L 4)
                    >.   (L  5)
                    >.   (L  6)
                    >.   (L  7)
                    >>>. (L 10)
                    >.   (L 11)
                    <<<<<<< (L 4)
                    - (L 4)
                ]
                <<< (L 1)
            ]
            >>> (L 4)
            [   ( Si es un menos)
                >.   (L  5)
                >.   (L  6)
                >.   (L  7)
                >.   (L  8)
                >>>.   (L 11)
                <<<<<<< (L 4)
            
                >.   (L  5)
                >.   (L  6)
                >.   (L  7)
                >.   (L  8)
                >>>.   (L 11)
                <<<<<<< (L 4)
                - (L 4)
            ]
            <<< (L 1)
        ]
        >>> (L 4)
        [   ( Si es una coma)
            >.   (L  5)
            >.   (L  6)
            >.   (L  7)
            >>>. (L 10)
            >.   (L 11)
            <<<<<<< (L 4)
            
            >.   (L  5)
            >.   (L  6)
            >.   (L  7)
            >.   (L  8)
            >>>.   (L 11)
            <<<<<<< (L 4)
            - (L 4)
        ]
        <<< (L 1)
    ]
    >>> (L 4)
    [   (Si es un mas)
        >.   (L  5)
        >.   (L  6)
        >.   (L  7)
        >>>. (L 10)
        >.   (L 11)
        <<<<<<< (L 4)
        >.   (L  5)
        >.   (L  6)
        >.   (L  7)
        >>>. (L 10)
        >.   (L 11)
        <<<<<<< (L 4)
        - (L 4)
    ]
    <<< (L 1)
    >[-] (Limpiando)  (L 2)
    >[-] (Limpiando)  (L 3)
    << (L 1)
    , (Se lee lo que el usuario dice)  (L 1)
]