Nota del autor

Si la entrada que estás leyendo carece de imágenes, no se ve el vídeo que teóricamente lleva incrustado o el código fuente mostrado aparece sin formato, podéis conocer los motivos aquí. Poco a poco iré restableciendo la normalidad en el blog.
Este blog es un archivo de los artículos situados previamente en Lobosoft.es y ha dejado de ser actualizado. Las nuevas entradas pueden encontrarse en www.lobosoft.es. Un saludo,
Lobosoft.

viernes, 29 de febrero de 2008

Atributos de NUnit 2.x

A la espera de las novedades que introducirá el lanzamiento de NUnit 3.0, vamos a presentar el uso de este unit-testing framework en la versión 2.4.x del mismo.


NUnit se presenta como una herramienta muy útil dentro del marco del desarrollo orientado a pruebas (TDD), permitiéndonos realizar las pruebas unitarias de forma automatizada y cubriendo todos los casos de uso que deban implementar las clases de nuestra aplicación. En el TDD, el flujo normal de desarrollo consiste en la escritura de las pruebas, escribir el código que debe pasarlas y hacer un refactoring para eliminar código duplicado. La escritura de las pruebas y la ejecución de los métodos que deben pasarlas correrá a cargo de NUnit.


El uso de NUnit se basa en el uso de atributos personalizados, que indicarán al framework de NUnit qué clases y qué métodos son los de pruebas, y qué pruebas deben realizarse sobre el código. Los atributos de NUnit en su versión 1.x eran nombrados según las convenciones del .Net Framework, pero esto cambió en la 2.x, usando ahora los atributos personalizados que pasamos a enumerar.


Atributos cuyo ámbito de uso es a nivel de clase:




  • TestFixture: Se usa para indicar que una determinada clase contiene métodos de prueba. Entre las restricciones para la clase están que deberá contar con un constructor por defecto (siendo válido el que proporciona automáticamente .Net) y que debe ser pública para que NUnit pueda acceder a ella para la ejecución de las pruebas.


Atributos cuyo ámbito de uso es a nivel de método:




  • Test: Su uso es indicar que un determinado método es un método de prueba. Entre las restricciones para el método de prueba estarán que no devuelva ningún valor (void) y no reciba parámetros, y que la clase a la que pertenezca esté marcada con el atributo TestFixture.



  • ExpectedException: Indica que el método va a producir una excepción del tipo indicado en el atributo (exactamente ese tipo, no otro distinto, aunque herede del mismo). La prueba se considera superada si al ejecutarlo lanza la excepción esperada.



  • TestFixtureSetUp: Inicializa el entorno de pruebas antes de ejecutarlas, es decir, establece las condiciones necesarias para que las pruebas se realicen en un ambiente idóneo. Se ejecutará antes que cualquier otro método. Sólo puede haber un método marcado con el atributo TestFixtureSetUp dentro de una clase TestFixture.



  • TestFixtureTearDown: Se encarga de restaurar el entorno creado para las pruebas por el método marcado con TestFixtureSetUp. Sólo puede haber un método marcado con este atributo dentro de la clase.



  • Setup: Inicializa y establece el entorno antes de la ejecución de cada prueba, es decir, justo antes de cada método de prueba que se ejecute. Generalmente se encarga de inicializar variables y dejar el entorno “limpio” para la ejecución de la prueba. Sólo puede haber un método marcado como Setup dentro de cada clase de pruebas.



  • TearDown: Su función es restaurar el entorno tras la ejecución de cada prueba unitaria. Sólo puede haber un método marcado como TearDown dentro de cada clase de pruebas.


El plan de ejecución de las pruebas será, por tanto, el siguiente:



Ejecución de las pruebas con NUnit


A nivel de método y clase tenemos los siguientes atributos:




  • Category: Otra opción que tenemos es agrupar las pruebas según categorías, de modo que podamos realizar la ejecución de un determinado bloque de pruebas simplemente indicando la categoría a la que pertenece la prueba. Para ello haremos uso del atributo Category, que puede usarse de forma conjunta a los atributos TestFixture o Test, es decir, a nivel de clase o de método.



  • Explicit: Obliga a indicar durante el proceso de pruebas que se incluya una determinada prueba en el mismo. Es decir, hay que indicar explícitamente que deseamos ejecutar una determinada prueba, siendo ignorada por NUnit en caso contrario.



  • Ignore: Es usado para ignorar una determinada prueba y no incluirla en el plan de pruebas. Al ejecutar NUnit, se marcará con amarillo, indicando que hay código sin probar. La ventaja de esto es que el código estará incluido en el ensamblado, ya que es compilado, pero lo excluimos de las pruebas igual que si todo el código del método o la clase hubiese sido comentado.


En la próxima entrega veremos un ejemplo de clase de pruebas haciendo uso de estos atributos y de otra de las características de NUnit, las aserciones (Asserts), que nos permitirán validar si el resultado esperado en las pruebas coincide con el que nos devuelve nuestro método probado.


Actualización (8 de abril de 2008): 

El blog registra una nueva entrada el 3 de abril de 2008 sobre Cheat Sheets, en concreto recogiendo una "hoja de trucos" o guía de Test-Driven Development, disponible para su descarga en formato PDF.

 

jueves, 28 de febrero de 2008

NUnit 3.0

La Programación Extrema o Extreme Programming (XP), es una metodología ágil de desarrollo basada en una serie de aspectos que permitirían un desarrollo permisivo y adaptable a los cambios de requisitos que se producen habitualmente durante el desarrollo de un proyecto. Una de las características fundamentales de este enfoque es el desarrollo orientado a pruebas (Test-Driven Development, o TDD), en el que las pruebas se suelen escribir antes incluso que el propio código que ha de superarlas. En este aspecto profundizaremos en una próxima entrada del blog, al incluir las pruebas unitarias en el desarrollo de nuestra aplicación con la Web Client Software Factory que introdujimos hace unos días. Sin embargo, el propósito de hoy no es otro que presentar una de las herramientas más usadas a este efecto en los desarrollos con tecnologías Microsoft .Net. Me refiero a NUnit, un framework de pruebas unitarias perteneciente a la familia xUnit, que sigue vigente hoy día, aun a pesar de la inclusión por parte de Microsoft de los proyectos de prueba (Test Projects) en las ediciones Team System de los IDE de desarrollo Visual Studio 2005 y 2008. Entre los motivos en los que me baso para afirmarlo se encuentran el pecuniario (los costes de una licencia de VSTS son mucho más elevados que los de un Visual Studio Professional + NUnit -que es gratuito-, y ya no digamos que los de un SharpDevelop o Eclipse con NUnit, que son nulos) y el de la portabilidad, ya que NUnit está disponible, por ejemplo, para plataformas Linux en las que podríamos estar desarrollando con Mono .


NUnit, en el momento en que escribo estas líneas, está disponible en su versión 2.4.6, que será la que usemos en las próximas entradas relacionadas con el TDD, pero está previsto el lanzamiento de la versión 3.0, que incluirá importantes cambios con respecto a la versión actual. Para empezar, su arquitectura estará basada en plugins, por lo que será mucho más extensible que NUnit 2.4.x, que permite la ampliación de sus funcionalidades mediante la incorporación de addins, pero está muy limitado a este respecto. La ventaja de las aplicaciones que permiten la incorporación de plugins es que, partiendo de una configuración básica, pueden personalizarse para cada usuario en concreto, haciendo la herramienta más útil para el mismo, y más adaptable al cambio.


La segunda característica que incorporará NUnit 3.0 es su arquitectura basada en tres capas: interfaz de usuario, motor de pruebas y framework xUnit.



Capas de NUnit 3.0


Esta división en capas permite que NUnit pueda usarse de diversas formas: mediante su propio inferfaz gráfico o en consola, usando NAnt, por ejemplo, para automatizar pruebas. También que las pruebas sean extensibles a varias plataformas, ya que NUnit 3.0 permitirá la ejecución de pruebas como un proceso separado, dependiendo de la versión del CLR, así como la ejecución distribuida de las pruebas en distintos puntos de una red mediante agentes remotos (Test Agents) . Por último, la capa de framework permite que las pruebas puedan hacerse en diferentes versiones del .Net Framework, en el Mono CLR y con el Compact Framework, en plataformas Linux y Windows, así como entornos de 32 y 64 bits.


Aunque faltan unos meses para poder disfrutar de la nueva versión de NUnit, todo parece apuntar a que la espera merecerá la pena.


Actualización (8 de abril de 2008): 

El blog registra una nueva entrada el 3 de abril de 2008 sobre Cheat Sheets, en concreto recogiendo una "hoja de trucos" o guía de Test-Driven Development, disponible para su descarga en formato PDF.

 

martes, 26 de febrero de 2008

La pérdida de conocimiento en la empresa actual

Hace unos meses, mientras buscaba información técnica sobre algún aspecto del desarrollo de software, encontré un artículo que me llamó enormemente la atención. Tras leerlo, lo compartí con algunos amigos, compañeros de profesión, y coincidieron conmigo en lo acertado del análisis que realiza sobre la pérdida de conocimiento que sufren, por decisión propia, tantas empresas del sector de la consultoría informática.


Aunque hay que admitir que en el mundo globalizado que nos ha tocado vivir merecen igualdad de condiciones un indio, que un latinoamericano o un europeo, y que la competitividad ha crecido -y seguirá haciéndolo- hasta límites inesperados, lo que no deja de sorprenderme es la facilidad con que las empresas “reponen” a los trabajadores que, tras meses o años de aprendizaje, deciden abandonar el barco antes de que, por el propio burn out producido por la insatisfacción profesional a que lleva el sentirse infravalorado, ardan las naves con el pasaje dentro. Y su puesto, como si nada hubiese ocurrido, llegará otra persona que partirá desde cero para intentar hacer crecer el árbol que plantó su predecesor, quien ya conocía cada hoja y cada brote del mismo.


Citando el artículo “Insourcing”, mejor que “outsourcing”:




Otro factor por el que el outsourcing no es interesante desde mi punto de vista, es que los que aprenden son otros. Cada vez que trabajas en la implementación de un sistema, por trivial que sea, aprendes algo, y ese conocimiento adquirido es algo que te va a ayudar en proyectos futuros. A las empresas siempre se nos llena la boca cuando hablamos de know how, pero se nos olvida que el know how, sólo nace de la experiencia, de la formación y de la capacidad para retener a nuestro personal. Llevar a cabo proyectos de software no es sólo una manera de ganarse la vida, sino también una excelente manera de aprender para poder abarcar proyectos futuros y poder seguir en el juego de ganarnos la vida. Sin ese proceso de aprendizaje de las empresas, es también muy difícil que se den las condiciones necesarias para que se produzca la innovación. Y todos los proyectos de desarrollo de software que triunfan son innovadores, en uno u otro sentido.



Se puede decir más alto, pero no más claro. O tal vez sí, de una forma ciertamente más lírica. Hace unos días, mientras leía la revisión que de la Ilíada hace Baricco, me encontraba con un texto que salvando distancias, puede asemejarse en buena medida al sentimiento de burn out que mencionaba anteriormente.



Habló Aquiles, diciendo:

Hijo de Laertes, divino de mente astuta, es mejor que hable claro y diga lo que pienso, y lo que sucederá: así nos evitaremos seguir charlando inútilmente. No hay en la tierra ni un solo aqueo que pueda convencerme de que abandone mi ira. No podrá hacerlo Agamenón, ni podréis hacerlo vosotros. ¿Qué provecho obtiene quien combate, siempre, sin tregua, ante cualquier enemigo? El destino es igual tanto para el animoso como para el bellaco, igual es el honor para el valiente que para el cobarde, y mueren igual el holgazán y el esforzado. Nada me queda después de haber sufrido tanto, después de haber arriesgado mi vida en todo momento en el corazón de la batalla. Como un pájaro que lleva a sus polluelos la comida que con tanto esfuerzo ha conseguido, del mismo modo pasé yo muchas noches insomnes, y muchos días dediqué a luchar contra el enemigo en el campo ensangrentado.

[…]

Ve a donde esté Agamenón y refiérele lo que te he dicho, y hazlo en voz alta, delante de todos, de manera que los demás aqueos sepan qué clase de hombre es, para que tengan cuidado, no vayan a ser engañados ellos también. Yo os digo que, por muy desvergonzado que sea, no volverá a tener el valor de mirarme a los ojos. Y yo no iré en su ayuda, ni combatiendo, ni dándole consejo; ya he tenido bastante, que se vaya al diablo, nada puedo hacer si se ha vuelto loco. Él ya nada me importa, y odio sus presentes: aunque me diera diez, veinte veces cuanto posee, aunque me ofreciera tantos bienes como granos tiene la arena, ni siquiera así lograría doblegar mi corazón. Antes tendrá que pagar, hasta el fondo, la horrible ofensa con que me ha herido.

(Alessandro Baricco, Homero, Ilíada)

Para profundizar en el tema:

Expresiones lambda vs Delegados y métodos anónimos

En la entrada anterior vimos cómo usar las expresiones lambda para formular con una sintaxis compacta y clara una serie de ecuaciones matemáticas en el .Net Framework 3.0 (y 3.5). Avanzamos también la relación existente entre esta notación y la declaración de un delegado y un método anónimo para implementar la misma funcionalidad, y cómo, hasta cierto punto, si las expresiones lambda hubiesen aparecido en la versión anterior del framework, podrían haber suplido la función de los métodos anónimos, brindando además una mayor funcionalidad, como el uso de bloques de código como datos y el uso de árboles de expresión, aspectos en los que profundizaremos más adelante, pues dotan a C# de características propias de la metaprogramación.


El propósito de hoy, sin embargo, es complementar al artículo de ayer, en el que afirmaba la íntima relación existente entre las expresiones lambda y los métodos anónimos y delegados, como avanzaba hace un momento. Para demostrarlo, haremos uso de la excelente herramienta Reflector, de Lutz Roeder, que permite desensamblar código objeto generado para el .Net Framework y mostrarlo en varios de los lenguajes que soporta (C#, VB.Net y el propio IL, entre otros).


Si abrimos, usando Reflector, la DLL correspondiente al ejemplo de ayer, en el que implementábamos una clase que nos ofrecía la funcionalidad de cálculo del interés simple en matemáticas financieras, nos encontraremos con una serie de peculiaridades.



Estructura de la clase Financiera


Como podemos apreciar, en el ensamblado se encuentran, además de los métodos que definimos en la clase, otra serie de métodos y delegados con nombres generados automáticamente. Si comprobamos el contenido de los mismos, pulsando sobre su nombre en el árbol de exploración de Reflector, nos encontraremos con un delegado “vacío”, correspondiente a la expresión lambda que definimos con nuestra ecuación para el interés.


Delegado “Interes”


El analizador de Reflector (botón derecho, y opción analizar) nos indica las dependencias del método y por cuáles otros es usado. En la secuencia de figuras que se muestran a continuación se puede comprobar que nuestra expresión lambda ha sido convertida internamente en un método anónimo y un delegado, ambos privados.




Método que implementa nuestra funcionalidad para el interés simple
La implementación de nuestra funcionalidad inicial



El método abstracto y delegado con sus dependencias
El delegado con sus usos y dependencias

La clase ofrecerá la funcionalidad a través de un delegado público que implementa el tipo genérico System.Func. Finalmente, el código de la clase quedará:



Código de la clase, según el desensamblador


Con ésto hemos demostrado la relación existente entre las expresiones lambda y los delegados y métodos anónimos que indicábamos ayer.

Expresiones Lambda en C#

Ya he hablado en otras ocasiones sobre la incorporación de las expresiones lambda al .Net Framework a partir de su versión 3.0. Este tipo de expresiones, en las que profundizaremos hoy, proporcionan al framework el soporte necesario para el uso de LINQ como lenguaje de consulta casi, diríamos, universal. Lo primero que llama la atención al ver la implementación de las expresiones lambda en .Net es que, de haber aparecido antes, no habrían sido necesarios los métodos anónimos que se incorporaron en la anterior versión del framework (.Net 2.0). Es más, en cierto modo constituyen -entre otras mejoras- un embellecimiento del código y un (permítasenos la licencia de llamarlo así) encapsulamiento del método anónimo y del delegado que lo incluye. Esta relación, y cómo se definen las expresiones lambda, será el tema principal de la entrada de hoy.


En el cálculo del interés simple, dentro del campo de las matemáticas financieras, entran en juego una serie de ecuaciones que deseamos implementar en nuestro código.


Interés = Capital * Tiempo * Tasa de interés
Valor Futuro = Capital * (1 + Tasa * Tiempo)
Capital = Valor Futuro * (1+ Tasa * Tiempo) -1

Si deseáramos implementar estas funciones mediante el uso de métodos anónimos, deberíamos hacerlo a través de un delegado. Por ejemplo, la función que define el Interés podría implementarse como sigue:


[csharp]
private static double MiInteres(double C, int t, float i)
{
return ((C * t) * i);
}
[/csharp]

Para poder asignarla a un delegado, deberíamos tener definido un delegado con su misma firma:


[csharp]public delegate double Func(double C, int t, Single i);[/csharp]

La asignación, entonces, sería automática:


[csharp]Func miInteres1 = MiInteres;[/csharp]

Sin embargo, los métodos anónimos nos brindan un método más compacto y elegante para obtener el mismo resultado:


[csharp]Func miInteres2 = delegate(double C, int t, Single i) { return C * t * i; };[/csharp]

La definición de Func, incluido en el espacio de nombres System.Linq como tipo genérico de delegado, es la que sigue (para un ejemplo con 0, 1 y 2 argumentos):


[csharp]
public delegate TResult Func();
public delegate TResult Func(T1 arg1);
public delegate TResult Func(T1 arg1, T2 arg2);
[/csharp]

Visto esto, ¿cómo podríamos realizar la implementación de nuestras funciones financieras usando expresiones lambda? Vuelvo a incidir en la cercanía de dichas expresiones con los lenguajes funcionales y en que, debido a esta característica, su declaración será compacta y precisa. Comencemos con la misma función que nos ha ocupado hasta este momento, la del cálculo del interés simple. Recordemos que esta función estaba definida como

Interés = Capital * Tiempo * Tasa de interés

La expresión lambda equivalente será
[csharp]
public static Func Interes = (C, t, i) => (C * t * i);
[/csharp]

Como vemos, el C# de los .Net Frameworks 3.0 y 3.5 incluye mediante las expresiones lambda una sintaxis mucho más clara y concisa que el que se conseguía mediante el uso de los métodos anónimos. Una posible implementación de las ecuaciones implicadas en el cálculo del interés podría ser la siguiente:


[csharp]
public static class InteresSimple
{
public static Func Interes =
(C, t, i) => (C * t * i);

public static Func ValorFuturo =
(C, t, i) => (C * (1 + i * t));

public static Func Capital =
(VF, t, i) => (VF * Math.Pow((1 + i * t), -1));
}
[/csharp]

Entre las ventajas que nos aportará el uso de las expresiones lambda frente al de métodos anónimos y delegados se encuentra no sólo la simplicidad y limpieza sintáctica de la expresión, sino también la posiblidad de usar bloques de código como datos (algo inherente a estas expresiones e imposible de conseguir mediante los métodos anónimos), una característica en la que profundizaremos en otra ocasión.

lunes, 25 de febrero de 2008

Mi ordenador es un zombi


Ghost’n Goblins - Ordenadores Zombi


Desafortunadamente el título de la entrada de hoy no parafrasea el de la conocida canción de Alaska y Dinarama, sino que hace referencia a la expansión que se viene produciendo desde hace un par de años de malware específicamente diseñado para facilitar la delincuencia en el ciberespacio. Por un lado, proliferan ataques de phishing que, haciendo uso de lo que en su día se dio en llamar “ingeniería social”, vulneran la privacidad de los usuarios robando sus contraseñas gracias a la inconsciencia de aquellos que, tras recibir un correo electrónico o una petición por cualquier método, incluido el telefónico, de su autenticación en el sistema informático de su banco, se prestan, sin mayor dilación, a hacerlo. La captura de las contraseñas se produce desde un sitio web muy similar al verdadero, que simplemente recoge la clave introducida por el usuario y, con probabilidad, informa al mismo de que la introdujo mal redirigiéndole después al sitio web verdadero, con lo que en el segundo intento puede acceder al sistema y piensa, ingenuo, que se equivocó la primera vez al teclear la contraseña.


Hay otros métodos más sofisticados, como el uso de troyanos u otro malware que, convenientemente instalado en el ordenador del usuario, usa keyloggers para recuperar todo lo escrito desde el mismo. Sin embargo, y ante la inclusión de los bancos de teclados virtuales en sus páginas, mediante los que solicitan al usuario la introducción de la contraseña en lugar de hacerlo a través del verdadero teclado, han aparecido troyanos que incluso realizan una grabación en video del momento clave (nunca mejor dicho) en el que el usuario introduce su contraseña haciendo uso del mencionado teclado virtual. A todos estos ataques de phishing habría que sumar los de pharming para comprobar que no estamos tan seguros como creemos en nuestra casa y frente a nuestros ordenadores personales.


¿Qué diríamos ahora si nos acusaran de formar parte de un equipo de ciberdelincuentes, de difundir SPAM (correo basura) entre miles de usuarios, de realizar ataques DoS a sitios web o distribuir pornografía infantil desde nuestro ordenador? Es decir, formar parte de los criminales, y no de las víctimas. Lo negaríamos, ¿verdad? Pero, ¿estamos seguros de no estar incurriendo en el delito que pretenden inculparnos? La respuesta debería ser un rotundo no. Evidentemente, desde Lobosoft deseamos creer en su inocencia, y que está siendo víctima de otro tipo de ataque que prolifera actualmente: convertir su ordenador en un zombi mediante la instalación de un software malicioso que permita al atacante controlarlo y usarlo para perpetrar todo tipo de delitos; desde enviar correo publicitario no deseado a realizar ataques de denegación de servicio, pasando por su uso como pasarela a otros sistemas informáticos consiguiendo, mediante una serie de “saltos”, ocultar su rastro ante posibles rastreos de la policía científica.


La proliferación de equipos zombis en los últimos años ha sufrido un crecimiento exponencial en todos los países desarrollados. El nuestro, con un afán loable de superación, España es el segundo país dentro del ranking Europeo de ordenadores infectados por este tipo de malware, según un informe de la Europol fechado en agosto del pasado año, por lo que existe una alta probabilidad de que ahora, desde su equipo, se esté compartiendo pornografía o esté enviando correos con publicidad sobre alargamiento del miembro viril masculino a cientos de usuarios, hastiados ya de recibir este tipo de información.


Ante todo esto, ¿cómo actuar? Sin duda, instalando en su equipo y manteniendo actualizado un antivirus, software de protección anti-spyware y algún firewall. Y, ante todo, actuando siempre con la máxima prudencia.


Para saber más:



viernes, 22 de febrero de 2008

Olvido de contraseñas en Windows

Ophcrak logo 


¿Cuántas veces habrá acudido a nosotros un usuario desesperado porque no recuerda la contraseña de Windows? En entornos en los que existe un repositorio centralizado de contraseñas (léase LDAP y similares), el administrador de sistemas dará fin a la inquietud del usuario en un santiamén. Sin embargo, en equipos domésticos o pequeñas empresas eso es, cuando menos, ciencia ficción. Ante situaciones como la planteada es cuando demuestran su utilidad herramientas como las que presentaba hace unos días en la entrada sobre distribuciones Linux que incluyen herramientas de seguridad. Esta tarde he aprovechado para probar una de las más sencillas que pueda encontrarse: Ophcrack. Se trata de un LiveCD que incluye un SLAX Linux (una distribución bastante ligera) con la herramienta Ophcrack instalada. El uso de la misma es tremendamente complejo, por lo que conviene enumerar los pasos a seguir:




  1. Introducir el LiveCD en la unidad lectora del equipo.

  2. Reiniciar el ordenador.

  3. Esperar a que aparezca el menú de arranque y pulsar Enter.

  4. Se iniciará el sistema Linux. Montará automáticamente la partición Windows donde se encuentre el archivo SAM de contraseñas. Iniciará automáticamente OphCrack.

  5. Esperar.

  6. Esperar más.

  7. La lista de usuarios con sus contraseñas respectivas estará ante nosotros.


El ataque de Ophcrack está basado en tablas Rainbow, por lo que la fortaleza de las contraseñas será inversamente proporcional a la similitud de las mismas con palabras reales. En cualquier caso, existen tablas con caracteres especiales, y si ninguna de ellas consigue romper las claves, finalmente se produce un ataque por fuerza bruta. Por tanto, la duración del proceso irá en relación directa con la complejidad de las contraseñas de los usuarios.




Ophcrack LiveCD




Ophcrack es una herramienta recomendable que conviene tener siempre a mano, sobre todo si corremos el peligro de enfrentarnos a situaciones como la que planteaba en el inicio del post de hoy.

¿Quines o Virus?

Vuelvo a la carga con otro artículo sobre los quines, que ya presenté hace un par de días en el blog, para estudiar la similitud, como ya anuncia el título de la entrada, con los virus informáticos. Una comparación que no es gratuita, y que fue lo primero que se me pasó por la cabeza cuando conocí las características de un quine.


Si la impaciencia o afán de conocimiento os hicieron ir más allá del alcance del artículo anterior e indagar un poco en el tema, bien en los enlaces recomendados que incluía en el mismo, bien realizando alguna otra búsqueda, veríais que existe una considerable cantidad de páginas que tratan el tema (sobre todo en cuanto a lo que concursos de creación de quines se refiere), aunque pocas entran en suficiente profundidad en él. Al refrescar conocimientos estos días para eswcribir estas entradas, encontré una interesante serie de artículos en español que incluyo en los enlaces recomendados de hoy. Pero veamos, en primer lugar, por qué insisto en la relación entre quines y virus.


Una de las primeras cosas que todo [interesado|aficionado | apasionado|afectado] de los virus descubre es la capacidad de propagación de éstos. Es una de las características principales de un virus: es capaz de replicarse e infectar a otras aplicaciones. Partiendo de esta premisa, tenemos que un virus es un programa que tiene la capacidad de replicarse mediante la inclusión en otros de su propio código, donde a su vez podrá nuevamente reproducirse para continuar su propagación. Por tanto, aunque no se trate exactamente de un quine (que, recordemos, reproducía como salida su propio código fuente), la similitud es tan grande que merece la pena profundizar un poco más en ella.


Si nos pertrechamos de sombrero y látigo y nos dedicamos a practicar arqueología informática, encontraremos virus que guardaban similitudes con los quines. Por ejemplo, el virus
Urphin infectaba código fuente en Pascal justo antes de ser compilado. Residente en memoria, esperaba la ejecución de TPC.EXE, el compilador de Turbo Pascal. En ese momento, incluía su propio código justo tras el BEGIN del programa, permitía el proceso de compilación y limpiaba después el código fuente .PAS de todo rastro. Así, finalizaba el proceso con un código fuente limpio y un ejecutable infectado por el virus. Como vemos, un virus de y para programadores.


Esto ocurría en tiempos remotos, cuando aún no existía un control adecuado de los procesos, que se ejecutaban en zonas compartidas de memoria. Hoy día, con modernos sistemas como Windows Vista (TM) o las últimas distros de Linux, nada de esto puede pasarnos. Además, es un método burdo y arcaico para programar virus informáticos. Nada puede pasarnos, ¿verdad? Pues la verdad es que sí. Hoy día nos encontramos rodeados de lenguajes de script e interpretados: scripts de shell en Linux, VBScript, JavaScript, Phyton, e incluso de cuarta generación, como SQL, que pueden caer víctimas de este tipo de ataque.


Si pensamos en seguridad y en SQL, inmediatamente se nos vendrá a la cabeza el método de ataque por inyección de código SQL. Pero ¿podrían existir quines en SQL? La respuesta es un rotundo sí.


[sql]SELECT REPLACE(REPLACE('SELECT REPLACE(REPLACE("$",CHAR(34),CHAR(39)),CHAR(36),"$") AS Quine',CHAR(34),CHAR(39)),CHAR(36),'SELECT REPLACE(REPLACE("$",CHAR(34),CHAR(39)),CHAR(36),"$") AS Quine') AS Quine[/sql]

El código anterior es un quine programado en SQL. Más concretamente, en T-SQL, el SQL avanzado para bases de datos SQL Server de Microsoft. Se trata de un quine clásico, simplemente devuelve una sentencia SQL que es copia de sí misma. Pero se puede ir más allá. Estudiemos el código siguiente, esta vez preparado para bases de datos MySQL:


[sql]UPDATE ContainerContents SET OldContents='%content%' WHERE TagID='%id%'[/sql]

Se trata de una sentencia de actualización en base de datos. Simplemente actualiza un atributo de la tabla ContainerContents cuando se da una condición, que el identificador sea X. Ahora, el exploit que aprovecha la vulnerabilidad del TagID, que se presenta encerrado entre comillas, para copiar su código en el campo NewContents.


[sql]%content%' WHERE TagId='%id%';

SET @a='UPDATE ContainerContents SET NewContents=concat(\'%content%\\\' WHERE TagId=\\\'%id%\\\'; SET @a=\', QUOTE(@a), \'; \', @a); %payload%; --';

UPDATE ContainerContents SET NewContents=concat('%content%\' WHERE TagId=\'%id%\'; SET @a=', QUOTE(@a), '; ', @a); %payload%; --‘[/sql]

Vemos, en primer lugar, una línea con la parte final de la sentencia SQL original. A continuación, en otra línea, se define una variable “a”, una cadena de caracteres que incluye una sentencia de actualización además de a sí misma. Es, por tanto, el quine. Por último, en la tercera línea, se actualiza el contenido del atributo NewContents para cada registro y, junto a la actualización, se define la variable “a” con su contenido (escapamos a las comillas mediante la función QUOTE), con lo que el virus se está propagando en el sistema.


Existen quines de este tipo para cualquier sistema SQL, incluso para los más robustos (y caros) como Oracle:


[sql]Apples’, NewContents=(select SUBSTR(SQL_TEXT,43,127) FROM v$sql WHERE INSTR(SQL_TEXT,’’)>0)--[/sql]

Permite la apertura de una puerta trasera en el puerto 1234, ya que netcat abrirá un socket en nuestro servidor en modo de escucha, quedando a la espera de conexiones entrantes.


Como hemos podido comprobar, no queda tan lejano el uso de quines en el código de virus informáticos, constituyendo un riesgo real, y no sólo una teoría curiosa sobre metaprogramación. Aunque profundizaremos más adelante en este tema, en los enlaces recomendados podrás encontrar más información sobre el mismo.


miércoles, 20 de febrero de 2008

Web Client Software Factory

Un problema ante el que nos encontramos los desarrolladores hoy día es la falta de tiempo para adaptarnos a los constantes cambios a los que nos somete la industria del software. Hablaba hace unos días con un amigo sobre este tema, comentando los lanzamientos, recientes o inminentes, de Joomla 1.5, Drupal 6, WordPress 2.5, Code Igniter 1.6.1, Silverlight 2.0... enumeración que podría proseguir hasta terminar ocupando buena parte del artículo de hoy. Aunque existe una amplia comunidad de desarrolladores a nivel mundial que comparte su experiencia mediante foros, artículos técnicos, conferencias, etc., en muchas ocasiones esto no basta para que adquiramos el conocimiento necesario como para poder dar el salto a una nueva tecnología o experimentar lo suficiente con ella antes de llevarla a entornos de producción reales.


Ante este panorama, el afán de Microsoft por hacernos la vida más fácil es loable. Hace unas semanas hablaba de XNA 2.0, y de su entorno de trabajo integrado en Visual Studio que, mediante una serie de asistentes y recetas de código, permitía un desarrollo fácil e integrado de videojuegos para XBox 360 y PC, evitando la tediosa tarea de reinventar la rueda, ahora en .Net. Pasando a entornos menos lúdicos, y con una perspectiva ligeramente distinta, nos encontramos con Web Client Software Factory y Web Service Software Factory, dos factorías de software, como su propio nombre indica, enfocadas al desarrollo de aplicaciones y servicios web, y que Microsoft ofrece gratuitamente desde su equipo de Patterns&Practices.



WCSF Intro


 


La Web Client Software Factory (a partir de ahora, WCSF) incluye en la propia factoría software un conjunto de código reutilizable (bibliotecas y bloques de aplicación) que permitirá desarrollos más eficientes -en tiempo y costes- de los proyectos en que la usemos, una serie de recetas y plantillas para su uso integrado en Visual Studio, patrones de arquitectura y ejemplos que nos servirán como referencia a la hora de utilizar los recursos de la factoría.


WCSF incorpora dos bloques de aplicación. Por un lado, el Composite Web Application, enfocado a la creación de aplicaciones web ASP.NET bien estructuradas, y el Page Flow Application, con una orientación más clara hacia la nueva tecnología Workflow Foundation que incorpora el .Net Framework 3.5.


Lo primero que debemos hacer para comenzar a trabajar con WCSF es bajar la última versión de CodePlex e instalarla en nuestro equipo. Durante el proceso de instalación es conveniente comprobar que cumplimos con los requisitos necesarios para llevarla a cabo con éxito. El propio instalador incorpora una herramienta de verificación que nos permitirá descargar de Internet los componentes que nos sean necesarios y que no estén presentes en nuestro equipo.



Dependencias


Tras esto, obtendremos un nuevo tipo de proyecto dentro de los asistentes de Visual Studio, el Web Client Development Guidance Package, con la plantilla Web Client Solution.



Nuevo Proyecto


Si creamos una nueva aplicación usando dicha plantilla, nos encontraremos ante una solución con dos proyectos; el Shell, que no es más que una biblioteca de clases ubicada en una carpeta de Módulos, y un proyecto web, el DevelopmentWebsite. Esta división modular que implícitamente asume la plantilla permitirá el desarrollo paralelo de varios programadores sobre dicha solución de una forma totalmente independiente.


Vista inicial


También nos servirá, en nuestro caso, para adoptar algún patrón conveniente para nuestro desarrollo como, por ejemplo, el Modelo Vista Presentador (MVP), especialmente adecuado para la realización de pruebas unitarias. En este patrón de diseño la Vista (que se correspondería con la parte web de nuestra aplicación) apenas tiene peso específico, convirtiéndose así en un mero interfaz de comunicación con el usuario. Todo ello podrá ser gestionado desde el agregado al menú contextual de Visual Studio, o a través del navegador-guía para paquetes que habrá aparecido en nuestro IDE.


Navigate Guidance


En las siguientes entradas dedicadas a este tema profundizaremos, mediante un ejemplo completo, en el desarrollo de una aplicación web mediante el uso de WCSF y TDD (Test-driven Development, o Desarrollo Orientado a Pruebas).

Programas autorreplicantes

Desde que empecé a escribir en el blog de Lobosoft, deseaba dedicar una entrada a los quines, ya que me llamaron la atención desde siempre por sus peculiares características. Un quine, tal y como lo describe la Wikipedia, es un programa (un metaprograma, en realidad) capaz de replicarse a sí mismo. Es decir, que al ejecutarlo produce como salida una copia de su propio código fuente. Esto, que podría parecer una obviedad, no lo es tanto por la principal restricción que se les impone, a saber:



  • Un quine no puede abrir el fichero en el que está escrito (lenguajes interpretados) ni el de su código fuente (lenguajes compilados) para escribirlo en pantalla.


De este modo, la sencillez aparente que parecía subyacer en la programación de los quines desaparece por completo. Para verlo más claramente, estudiemos cómo programaríamos un quine en lenguaje C:


[c]
#include

int
main (void)
{
printf("#include \n\nint\nmain (void)\n{\n");
printf("printf(\"#include \\n\\nint\\nmain (void)\\n{\\n\");\n");
[/c]

Empezamos a programarlo y... ¡sorpresa! Parece que entramos en un bucle infinito. El programa comienza con la inclusión de los ficheros de cabecera necesarios y la declaración de la función main. A continuación, con printf escribimos en la salida estándar una cadena de caracteres con el comienzo del programa. En ese momento, hay que escribir una sentencia que escriba a la anterior, y ahí comienza nuestro ciclo sin fin.


Para resolver esta recursividad inherente a la propia escritura del quine, existen varios métodos, siendo el que veremos ahora uno de los más funcionales. Empezaremos por "escribir" todo el código de nuestro programa en un array de caracteres, y no en una cadena (string) que "envuelva" al código anterior y que, para ser escrita, necesite volver a ser incluida en otra cadena y así ad infinitum, en un equivalente programático de las muñecas rusas.


Un quine correcto y operativo, pero no muy elegante, podría ser el siguiente:
[c]
#include

int
main (void)
{
char *s1="#include %c%cint%cmain (void)%c{%c";
char *s2=" char *s%c=%c%s%c;%c char *s%c=%c%s%c;%c";
char *s3=" char n='%cn', q='%c', b='%c%c';%c";
char *sp=" printf(";
char *s4="%ss1,n,n,n,n,n);%c";
char *s5="%ss2,'1',q,s1,q,n,'2',q,s2,q,n);%ss2,'3',q,s3,q,n,'p',q,sp,q,n);%c";
char *s6="%ss2,'4',q,s4,q,n,'5',q,s5,q,n);%ss2,'6',q,s6,q,n,'7',q,s7,q,n);%c";
char *s7="%ss2,'8',q,s8,q,n,'9',q,s9,q,n);%ss2,'0',q,s0,q,n,'x',q,sx,q,n);%c";
char *s8="%ss3,b,q,b,b,n);%ss4,sp,n);%ss5,sp,sp,n);%c";
char *s9="%ss6,sp,sp,n);%ss7,sp,sp,n);%ss8,sp,sp,sp,n);%c";
char *s0="%ss9,sp,sp,sp,n);%ss0,sp,sp,n,n,n);%c return 0;%c}%c";
char *sx="--- This is an intron. ---";
char n='\n', q='"', b='\\';
printf(s1,n,n,n,n,n);
printf(s2,'1',q,s1,q,n,'2',q,s2,q,n); printf(s2,'3',q,s3,q,n,'p',q,sp,q,n);
printf(s2,'4',q,s4,q,n,'5',q,s5,q,n); printf(s2,'6',q,s6,q,n,'7',q,s7,q,n);
printf(s2,'8',q,s8,q,n,'9',q,s9,q,n); printf(s2,'0',q,s0,q,n,'x',q,sx,q,n);
printf(s3,b,q,b,b,n); printf(s4,sp,n); printf(s5,sp,sp,n);
printf(s6,sp,sp,n); printf(s7,sp,sp,n); printf(s8,sp,sp,sp,n);
printf(s9,sp,sp,sp,n); printf(s0,sp,sp,n,n,n);
return 0;
}
[/c]

Un poco críptico, sí señor, pero ayudará a desvelar un par de secretos de la programación de quines. Por un lado, si examinamos el código podremos ver que existen dos partes claramente diferenciadas. Una serie de definiciones de constantes, que constituyen, por así decirlo, el bloque de datos del programa, seguido por una serie de sentencias que serán las que se ejecuten, usando el bloque de datos para replicar su propio código. También encontramos, entre medias, una línea con un intron, que no es más que una parte de código que no aporta nada a la funcionalidad del quine y que, de no existir, no afectaría a su comportamiento.


El ejemplo de quine para C que presenta la Wikipedia es algo más sencillo, pero se basa en la misma filosofía:


[c]
#include
char*i="\\#include&ltstdio.h>",n='\n',q='"',*p=
"%s%cchar*i=%c%c%s%c,n='%cn',q='%c',*p=%c%c%s%c,*m=%c%c%s%c%c;%s%c",*m=
"int main(){return!printf(p,i+1,n,q,*i,i,q,*i,q,n,q,p,q,n,q,m,q,n,m,n);}"
;int main(){return!printf(p,i+1,n,q,*i,i,q,*i,q,n,q,p,q,n,q,m,q,n,m,n);}
[/c]

En una próxima entrada veremos cómo la programación de quines guarda una importante relación con la seguridad de los sistemas informáticos y la programación de virus (aparte, claro está, de prestarse a la celebración de concursos geek, donde resulta ganador quien escribe el quine más corto en un determinado lenguaje).


Referencias:



Ese Malvicio…

Logo Malvicio


"Quien no tenga algún vicio, que tire la primera piedra", podríamos plantear, y difícilmente aparecería alguien con la osadía de ser el primero en lanzarla. Por eso, y porque para muchos de nosotros el mundillo de los videojuegos y el de la programación son sendos vicios, junto a un grupo de amigos me he embarcado en el desarrollo de un portal que trate sobre dicha temática, entrando más a fondo en los temas y con un enfoque más plural del que podemos darle individualmente desde el blog de cada uno de nosotros.


De momento está disponible el blog, aunque con poquitas entradas aún, y pronto aparecerá el acceso a la web, con mucha más información, tutoriales y juegos para descargar. Como ya apuntaba uno de mis compañeros en su blog personal, LastGames, en adelante podrás encontrar todo sobre los videojuegos en Malvicio.com.


Se me perdonará, pues, este pequeño post de "autobombo" con el que abro hoy el blog. Desde hace unos días, la suscripción a las RSS de Malvicio aparece en la sección Otros Blogs, de Lobosoft, para estar al tanto de todos los avances en torno al mismo. Y ahora, ¡a disfrutarlo!

martes, 19 de febrero de 2008

MS-Oil (TM)

Hace unos días, el 15 de febrero, Microsoft anunciaba la publicación del formato de los archivos binarios de Office. Ha costado años, pero por fin está aquí. Esta apertura de la información sobre cómo Word, Excel o Powerpoint, entre otras aplicaciones, gestionan y almacenan la información permitirá una mayor compatibilidad de iniciativas libres, como OpenOffice, obligado hasta el momento a llevar a cabo prácticas de ingeniería inversa para "intuir" el modo en que almacena la información el paquete ofimático estrella de Microsoft. Así que, a partir de ahora, la exportación de archivos de MS-Office a OpenOffice y viceversa podría darse sin mayor problema. ¡Albricias!, podríamos exclamar. Todo perfecto, ¿verdad? Pues la verdad es que no.


Cabría cuestionarse los motivos que subyacen a la decisión de Microsoft de mostrar precisamente ahora lo que hay en la trastienda de Office. ¿Por amor al arte, a la tecnología, o por un arrebato de buena voluntad? La verdad es que me cuesta aceptar que sea así, y tengo mis motivos.


Cualquier usuario afirmaría ahora que a él -o a ella- el Office de Microsoft le viene como anillo al dedo, y que para escribir cuatro cartas y llevar las cuentas de la casa lo que le viene bien es un programa que lo tenga todo y no dé problemas. Que en la oficina al friqui de turno se le ocurrió llevar una vez el OpenOffice ese y luego no había tabla que quedase alineada como esperábamos o documento que se abriese sin mayor dificultad. En esencia, todo eso es cierto, pero ¿quién provoca el problema?


Para dar con ello, habría que esbozar al menos la historia de OpenOffice, que es ciertamente interesante. Un grupo de desarrolladores (personas y empresas) se dedicaron a crear y promocionar un formato universal y libre para los documentos (el ODF u Open Document Format), y llegaron a conseguir su aceptación dentro del estándar ISO 26300. Algún tiempo después, fue adoptado como estándar por OASIS (Organization for the Advancement of Structured Information Standards), y su evolución se producirá dentro del control de dicha organización. Es decir, si el formato de los archivos de nuestros documentos cumple los estándares, nos aseguramos de que podrán ser abiertos y editados en cualquier programa compatible, dando igual, por tanto, la aplicación que hubiese sido usada para crearlos. En consecuencia, tendremos la posibilidad de elegir el programa que más nos guste o se adapte a nuestras necesidades (y a nuestro bolsillo) sin necesidad de preocuparnos por los que usen los demás.


Microsoft, por otro lado, lanzó hace poco su formato OOXML (Office Open XML), coincidiendo con su nuevo producto estrella, Office 2007. Dicho formato no es compatible ni tan siquiera con las versiones anteriores de Office, con lo que Microsoft se asegura que los usuarios deban actualizar sus licencias. Si, aunque sea poco a poco, todo nuestro entorno va actualizándose a Office 2007, no nos quedará más remedio que hacerlo, o perderemos la capacidad de intercambiar documentos (información, al fin y al cabo) con otras personas. Si a los particulares sumamos empresas y organismos públicos (que, recordémoslo, adquieren esas licencias con el dinero de nuestros impuestos) veremos que la situación no nos es ajena en absoluto. Y es que ni Windows ni Office "vienen gratis" con el ordenador que adquirimos.


Rizando el rizo, Microsoft pretende ahora obtener una certificación ISO para Open XML como si se tratase de un formato estándar -cuando de abierto lo único que tiene es el nombre-, saltándose a la torera la existencia de ODF, que sí es un estándar aprobado por los organismos competentes.


Si lo pensamos desde otra perspectiva, el caso que nos ocupa podría asemejarse a tener un coche para el que sólo nos sirviese el carburante de una determinada compañía. ¿Nos arriesgaríamos a salir a la carretera sabiendo que sólo podremos repostar "MS-Oil 2007", sin posibilidad de hacer otra elección? Yo, sinceramente, no.


bannerooxmlnoapto.gif


Si deseas apoyar la campaña en contra de la aceptación de OOXML como un estándar ISO puedes firmar en la dirección: http://www.noooxml.org/petition-es/

lunes, 18 de febrero de 2008

Ook!

No hace mucho la Universidad de Kioto publicaba en Current Biology una investigación sobre la capacidad de memoria de los chimpancés, estudio en el que se demostraba que pueden llegar a poseer una mayor retentiva numérica que muchos humanos.


Chimpancé pensando


El siguiente paso a dar será dotarles de un lenguaje de programación adecuado, y en este sentido una evolución de Ook! podría llegar a ser lo más adecuado. Hace unos días leía unos artículos sobre lenguajes de programación esotéricos, que no son otros que los creados por los desarrolladores como mera diversión y sin ninguna utilidad más que la de mantener vivo el estigma de friquismo que nos acompaña desde tiempos inmemoriales. En la entrada de introducción a F# que presentaba días atrás, incluía el código en brainfuck para la sucesión de Fibonacci. Por definición, estos lenguajes son Turing completos, es decir, son capaces de representar cualquier programa que pueda ejecutarse por la máquina universal de Turing, y la propia sintaxis de un programa en brainfuck recuerda muchísimo al funcionamiento de la misma.


Ook! es otro lenguaje de programación esotérico, basado en brainfuck y, por tanto, Turing completo. Su creador se basó en el bibliotecario de la Universidad Invisible del Mundodisco (mundo de ficción creado por Terry Pratchett en una saga absolutamente recomendable) para darle nombre. En la página oficial de Ook! se especifican los principios de diseño que lo rigen:




  • Ser un lenguaje de programación que pueda ser escrito y leído por orangutanes.

  • Con este fin, la sintaxis debe ser simple, fácil de recordar y no mencionar la palabra "mono".

  • Las bananas son buenas.


Basándose en estos principios, el lenguaje sólo consta de tres palabras reservadas ("Ook.", "Ook!" y "Ook?"), que proporcionan ocho sentencias como resultado de todos los emparejamientos posibles (23=8). Realmente, y a fuer de ser sinceros, hay que admitir que el lenguaje no es más que una mera parodia de brainfuck. Las ocho sentencias se corresponden con las proporcionadas por los ocho caracteres de brainfuck, y los "Ook" no son más que "ruido", pero no deja de resultar curioso ver algún programa escrito en este lenguaje. Además, los desarrolladores .Net nos encontramos de enhorabuena, ya que existe un compilador de Ook! para el mismo. Su nombre es Ook#, y puede descargarse de su web junto a código fuente de ejemplo.


Por último, dejo aquí un pequeño programa escrito en este interesante lenguaje de programación. Se trata, por analogía con el código presentado hace unos días, del algoritmo para el cálculo del la sucesión de Fibbonacci:




Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook.
Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook.
Ook. Ook? Ook. Ook? Ook. Ook. Ook. Ook? Ook. Ook?
Ook. Ook. Ook! Ook? Ook! Ook? Ook. Ook. Ook. Ook.
Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook? Ook.
Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook.
Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook! Ook!
Ook? Ook! Ook? Ook. Ook! Ook. Ook. Ook? Ook. Ook.
Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook.
Ook! Ook? Ook? Ook. Ook! Ook! Ook! Ook! Ook! Ook!
Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook!
Ook. Ook? Ook! Ook! Ook? Ook! Ook. Ook. Ook? Ook.
Ook? Ook. Ook? Ook. Ook? Ook! Ook? Ook. Ook! Ook.
Ook. Ook? Ook. Ook? Ook. Ook? Ook. Ook? Ook! Ook?
Ook! Ook! Ook? Ook. Ook! Ook? Ook? Ook. Ook. Ook.
Ook. Ook? Ook. Ook? Ook. Ook. Ook? Ook. Ook! Ook!
Ook? Ook! Ook? Ook. Ook! Ook? Ook. Ook? Ook. Ook.
Ook? Ook. Ook! Ook! Ook! Ook? Ook. Ook? Ook. Ook.
Ook? Ook. Ook! Ook! Ook! Ook? Ook. Ook? Ook. Ook.
Ook? Ook. Ook! Ook! Ook! Ook? Ook. Ook? Ook. Ook.
Ook? Ook. Ook! Ook! Ook! Ook? Ook. Ook? Ook. Ook.
Ook? Ook. Ook! Ook! Ook! Ook? Ook. Ook? Ook. Ook.
Ook? Ook. Ook! Ook! Ook! Ook? Ook. Ook? Ook. Ook.
Ook? Ook. Ook! Ook! Ook! Ook? Ook. Ook? Ook. Ook.
Ook? Ook. Ook! Ook! Ook! Ook? Ook. Ook? Ook. Ook.
Ook? Ook. Ook! Ook! Ook! Ook? Ook. Ook? Ook! Ook?
Ook! Ook! Ook? Ook! Ook. Ook? Ook. Ook? Ook. Ook.
Ook. Ook? Ook. Ook? Ook! Ook? Ook! Ook! Ook? Ook!
Ook. Ook. Ook? Ook. Ook? Ook. Ook? Ook. Ook? Ook.
Ook? Ook. Ook! Ook! Ook! Ook? Ook. Ook? Ook. Ook.
Ook? Ook. Ook! Ook! Ook? Ook! Ook? Ook! Ook? Ook!
Ook? Ook! Ook? Ook! Ook? Ook! Ook? Ook! Ook? Ook!
Ook? Ook! Ook? Ook! Ook? Ook! Ook. Ook? Ook. Ook?
Ook! Ook? Ook? Ook. Ook? Ook. Ook. Ook. Ook. Ook?
Ook. Ook? Ook! Ook! Ook? Ook! Ook. Ook. Ook. Ook?
Ook. Ook? Ook. Ook? Ook? Ook! Ook? Ook. Ook? Ook.
Ook? Ook. Ook? Ook!


Y luego diremos que nos llaman friquis ;) .

LINQPad

LINQPad Logo


El gran cambio en el .Net Framework desde la versión 2.0 a la 3.5 ha sido la incorporación de LINQ (Languaje Integrated Query), un lenguaje de consulta que viene a hacer las veces, en cierto modo, de un O/RM para .Net. Con LINQ podemos realizar consultas desde cualquier fuente de datos (BBDD, XML, colecciones de objetos...) y manipular los resultados de las mismas.


Ante este panorama, a los desarrolladores .Net no nos queda más opción que la de ponernos manos a la obra con este nuevo "juguetito", y para ello nada mejor que usar las herramientas adecuadas. Aunque Visual Studio 2008 da soporte a LINQ y los lenguajes que lo usan permiten aprovechar los recursos de IntelliSense y la validación de sentencias en tiempo de compilación, he encontrado un editor mucho más ligero para trabajar con LINQ, el LINQPad. Permite establecer conexión con diversas fuentes de datos, la importación de espacios de nombres y la depuración y ejecución de LINQ. Además, la última versión incorpora más de 200 ejemplos prácticos, listos para ejecutar y aprender LINQ, procedentes del libro C# 3.0 in a Nutshell.


Ahora sí que no tenemos excusa para no aprender LINQ.



LINQPad en ejecución.

Métodos de extensión en .Net Framework 3.5

Entre las numerosas novedades que atesora la nueva versión del framework de desarrollo de Microsoft se encuentra la que han dado en llamar "métodos de extensión" o "extension methods", que no son más que una forma de proporcionar funcionalidad a clases en las que no podemos hacerlo mediante herencia convencional, como ocurre, por ejemplo, con las clases selladas.


Por ejemplo, imaginemos que necesitamos un método para que, dada una determinada cadena de caracteres, genere un código HTML válido a partir de la entrada. Es decir, que sustituya los caracteres acentuados y especiales por sus equivalentes (por ejemplo, "Á" por "&Acute;", "ñ" por "ñ", etcétera). Dado que la clase String no permite la herencia, una opción hasta ahora habría sido crear una clase de utilidades donde incluir el método que implementase la nueva funcionalidad que necesitamos. Sin embargo, esto es poco intuitivo, y un programador que llegase al proyecto donde usamos este método no tendría porqué saber que existe una clase "MisUtilidadesDeTexto", por ejemplo, donde se implemente este método. Ni tan siquiera un IDE como Visual Studio sería capaz de mostrar ese método relacionado con la clase String. La idea que subyace tras todo esto es tener un método al que llamar en la forma


string str = mitexto.ToHTML();


que funcionase así de forma similar a mitexto.ToLower(), por poner un ejemplo.


Una posible solución a esto es la que propone Microsoft en su .Net Framework 3.5 mediante el uso de los métodos de extensión. Básicamente, estos métodos permiten ampliar la funcionalidad de una clase sin hacer uso de la herencia. Sí, es algo para tirarse de los pelos, lo admito, y que echa por la borda buena parte del paradigma de la programación orientada a objetos. Sin embargo, tras haberlo usado un poco, he de coincidir en que es una herramienta que ahorra bastante trabajo en determinadas ocasiones, aunque hay que andarse con mucho cuidado para no abusar de ella.


La forma de implementar y usar un método de expansión resulta francamente sencilla. Basta con definir una clase estática que implemente los métodos de extensión que necesitemos. En la definición del método, la única restricción es que el primer parámetro debe ser declarado del tipo de la clase que deseamos "enriquecer" y usando el modificador this.



[csharp]
public static class HtmlStringUtils
{
public static string ValidHtmlChar(this string s)
{
foreach (KeyValuePair kvp in diccionarioHTML)
{
s = s.Replace(kvp.Key,kvp.Value);
}
return s;
}
}
[/csharp]

Ahora, simplemente, podemos llamar a dicho método desde las clases principales de nuestra solución, e IntelliSense nos mostrará información sobre el mismo, entre otra, que se trata de un método de extensión.



IntelliSense con métodos extendidos


Si deseamos definir métodos con más parámetros, lo único que hemos de tener en cuenta es que el primero debe definirse tal y como se indicaba anteriormente. Por ejemplo, un método que encierre nuestro texto dentro de una determinada etiqueta HTML podría ser el siguiente:



[csharp]
public static string AplicarEtiqueta(this string s, string etiqueta)
{
return "" + s + "";
}
[/csharp]

y la llamada correspondiente podría ser algo como


string miHtml = "Hola mundo en " + "negrita".AplicarEtiqueta("STRONG");


que devolvería el HTML Hola mundo ennegrita correspondiente a la presentación "Hola mundo en negrita".


Hasta aquí todo perfecto. Sin embargo, existe una serie de problemas subyacentes, como la dependencia de los métodos de extensión de la clase que extienden, y que una posible evolución de esta los deje en estados inconsistentes o erróneos o, simplemente, que pierdan su funcionalidad.


Otra cuestión que hemos de considerar es la posibilidad de que futuras implementaciones de la clase incluyan métodos de igual nombre y parámetros, que provocarían que los de la instancia prevaleciesen sobre los de extensión, de manera que éstos no llegaran a ejecutarse ya que, por seguridad, siempre se ejecutará antes un método de instancia evitando así el posible "secuestro" de nombres de métodos.


Otro posible error podría derivarse de la definición de dos métodos de extensión de igual nombre pero ubicados en distintos espacios de nombres, por lo que la ejecución de uno u otro sólo dependería del que referenciásemos mediante using en nuestro código.


Por tanto, y resumiendo, nos encontramos ante un aspecto más que deberemos considerar en el desarrollo con el .Net 3.5, pero que no convendrá descuidar si optamos por incluirlo finalmente en nuestros proyectos.

domingo, 17 de febrero de 2008

Escribiendo, que es gerundio

w.bloggar Logo


Cuando decidimos crear un blog, nuestro primer afán es mantener una línea coherente y continua de escritura. Esto es particularmente evidente en blogs de temática determinada, y extensible hasta los más generalistas. Los primeros pasos suelen centrarse en decidir qué CMS usaremos en nuestro blog (si el proporcionado por Google con su Blogger o algún otro que nos sea brindado por la infinidad de empresas que ofrecen este servicio, como el propio WordPress, o instalar y usar una solución específica, si contamos con algún proveedor de hosting y deseamos tener más control sobre nuestro blog, los plugins y temas visuales que deseamos instalarle, etc. Después de todo esto, lo habitual es configurar el blog, personalizarlo en mayor o menor medida y, por último, comenzar a escribir e intentar que las obligaciones y falta de tiempo no nos lleven a abandonar la afición que con tanta ilusión emprendemos.


Durante el proceso de escritura del blog lo habitual es que nos baste con usar la propia interfaz de administración que proporcione el CMS y, a lo sumo, un editor de textos, como el genial OpenOffice, para redactar los textos y llevarlos al blog simplemente para ser publicados. El problema surge cuando, en lugar de mantener un solo blog, escribimos en varios. En este caso -que es el mío-, además del trabajo enumerado, nos encontramos con una serie de tareas repetitivas que resultan, cuanto menos, tediosas. Identificarse en cada servidor, acceder al panel de gestión del blog, redactar o insertar el texto, revisarlo y, finalmente, publicar la entrada.


Afortunadamente, existen herramientas como la que presento hoy, que me ha encantado. Permite la gestión de varias cuentas de usuario en los sistemas de publicación más extendidos (Blogger, Wordpress, Blogalia, TypePad, Drupal...) , y proporciona un entorno de trabajo común para todos ellos. Tan simple como conectarse al blog en el que deseemos añadir una entrada, escribir el post o recuperarlo si lo grabamos previamente para editarlo y, cuando esté listo, publicarlo. Su nombre es w.bloggar, y puede descargarse desde su página oficial, tanto en versión convencional como para dispositivos portátiles. A continuación puede verse esta misma entrada siendo editada desde esta aplicación:



w.bloggar

Vacas flacas (3ª parte)

En la tercera entrega de la serie Vacas Flacas vamos a ver cómo usar un terminal telnet para conectarnos y hablar en un servidor de IRC. La utilidad de esto no es tanto usar telnet para hablar con nadie (máxime si tenemos en cuenta que en los últimos años los servidores de IRC sufrieron el duro golpe de los bots, y que los usuarios, acostumbrados a los efectos visuales más llamativos de varias aplicaciones de mensajería instantánea, fueron dejando de lado el arcaico mIRC), sino para observar cómo un atacante a nuestro sistema puede usar unos mecanismos que no esperaríamos, y cómo se relacionan, sobre todo, los distintos protocolos existentes en Internet. Al pie de la entrada se pueden encontrar enlaces a los RFC de ambos protocolos.


Para saber que es posible llevar a cabo lo que pretendemos, vamos a leer el RFC del protocolo IRC. Ahí se nos indica que "a pesar de ser un protocolo de 8 bits, los delimitadores y palabras clave son tales que el protocolo se puede usar desde un terminal USASCII y una conexión telnet ". Justo lo que pretendemos conseguir.


Básicamente, la curiosidad de hoy consiste en hacer telnet a un servidor de irc. Para conseguirlo, desde la consola de comandos o el shell de nuestro sistema, escribimos:


telnet nombre.del.servidor puerto

Por ejemplo:

telnet libres.irc-hispano.org 6667

Tras esto, se establecerá una conexión mediante telnet al servidor de IRC.


Conexión


A partir de ahora, deberemos dar las órdenes necesarias para obtener un nick (alias) en el sistema. Al hacerlo, mediante el comando nick, el servidor nos enviará un ping, que deberemos responder para no ser desconectados del sistema. Hemos optado por identificarnos antes, además, en el sistema, mediante la orden user ident:



Nick


pong


Y respondemos con pong (id) al ping que envió el sistema remoto.


pong 2


En este momento, se producirá la conexión al servidor, recibiendo gran cantidad de información.


05.png


Y ya sólo nos quedará acceder a los diferentes canales (salas de charla) y hablar con otros usuarios del sistema. Para ello, usaremos las órdenes:

join #nombre_canal
part #nombre_canal
privmsg [#nombre_canal | nombre_usuario] mensaje

Para entrar en un canal, salir del mismo, y enviar un mensaje a un canal o usuario, respectivamente. Podremos pedir también una lista de los comandos existentes, simplemente escribiendo help.


06.png


Y listo, nuestro telnet es ahora un cliente de IRC.

Enlaces relacionados:

sábado, 16 de febrero de 2008

Vacas flacas (2ª parte)

En la anterior entrada del blog presentaba una curiosa forma de "navegar" por Internet. Podíamos solicitar a un servidor de www-mail una página web o algún recurso en la red (generalmente, la propia página HTML, las CSS asociadas a la misma, imágenes o sonidos que incluyese, etcétera), y al final del mismo lanzaba una pregunta en torno a la utilidad que, hoy día, podía darse a un recurso que, recordemos, usé en el pasado cuando por motivos administrativos limitaron el tipo de servicios de Internet que podíamos disfrutar los alumnos de la ETSI-Informática de la Universidad de Granada.


Bien, planteémonos la siguiente situación: nos encontramos en las instalaciones de un cliente realizando un despliegue de alguna aplicación, o revisando algún problema en el sistema. Necesitamos descargar, pongamos, el último parche de seguridad, o una determinada aplicación y nos encontramos con que los puertos de FTP (20 y 21, como command port y data port respectivamente) se encuentran cerrados, y también han limitado la navegación para evitar distracciones y relajamiento por parte de los trabajadores. El administrador de red no está disponible o, simplemente, no sabe/no contesta. Podríamos cerrar la sesión y darnos por vencidos, pero no es nuestra actitud, nunca. Así que comprobamos si los usuarios cuentan con correo electrónico con salida al exterior (fuera de la Intranet, a Internet), y de ser así, nos aprestamos a realizar una consulta vía www-mail a nuestro buscador preferido y, recibida la respuesta de dónde descargar la aplicación o recurso que necesitemos, procedemos a descargarlo con otra petición a www-mail. Es más, el que recomendábamos ayer no sólo permite conexiones mediante HTTP, sino también a sitios FTP, por lo que tenemos ambos recursos disponibles para realizar la descarga.


Pasarán unos minutos, recibiremos nuestro archivo, y podremos proseguir con nuestro trabajo sin mayor problema.

viernes, 15 de febrero de 2008

Vacas flacas (1ª parte)

Los malos tiempos agudizan el ingenio, y esto es cierto en todos los aspectos de la vida. Con esta serie de Vacas Flacas que comienzo hoy me retrotraigo a la etapa universitaria en la que, en mi caso, Internet era un lujo, aún existía Netscape, e Internet Explorer acababa de nacer en Windows 95. Durante diversos periodos los administradores de la red de la Universidad de Granada y de la propia ETSII de Informática se empecinaron en ponernos difícil navegar, descargar archivos o, en la mayor parte de los casos, chatear con aquel primerizo mIRC.


De entre todos estos obstáculos, uno de los más fáciles de sortear fue el impedimento para navegar por Internet, que duró algo menos de un mes y en el que, salvo los estudiantes de doctorado, sólo nos quedó el acceso al correo, para el que usábamos irremediablemente Pine o Eudora. En aquel momento, la solución fue "navegar" haciendo uso del e-mail. Hoy día nos parecería una locura, pero habida cuenta que por aquel entonces usábamos en ocasiones Lynx, el navegador de texto, desde nuestro terminal Unix, podemos afirmar que éramos verdaderos geeks, aunque no supiésemos ni que existía la palabra en cuestión.



Lobosoft visto con Lynx


Pero, ¿cómo se navega a través del correo? Como ya adelantaba, se trata de un sencillo proceso que consiste en realizar la solicitud a direcciones de correo que nos proporcionan dicha funcionalidad y que, por regla general, se encuentran ubicados en servidores de alguna Universidad o centro privado. La secuencia de pasos es tan simple como enviar un correo a una dirección determinada, que no es otra que la de un servicio de www-mail, y en el cuerpo del mensaje incluir una serie de órdenes (obtén tal página, descarta este archivo...). La respuesta no suele ser inmediata, ya que estos servidores suelen tener una carga considerable de trabajo, pero cuando nos llega el mensaje de respuesta, simplemente debemos reconstruir los archivos recibidos. Los archivos binarios llegaban entonces como archivo de texto con notación UUE (UU-Encoding) y debíamos usar herramientas como uuencode o uudecode para reconstruir el archivo original.


Generalmente, lo ideal es comenzar enviando el mensaje "HELP", ya que los servicios de www-mail pueden presentar variaciones en el conjunto de comandos que ofrezcan. A la vuelta, recibiremos un correo con la lista de operaciones que podemos llevar a cabo con ellos. Uno de los que siguen activos es el que hemos usado para nuestras pruebas. Escribiendo a la dirección www4mail@wm.ictp.trieste.it recibimos un correo con información sobre el servicio, y un enlace a su página principal, http://www4mail.org/, desde donde se puede obtener un manual de usuario actualizado. Una de las ventajas que incorpora es que podemos recibir nuestra respuesta como cuerpo del mensaje que recibamos (y vernos obligados a usar uudecode para convertir el archivo a su formato original), o como archivo adjunto, ya que el desarrollo posterior de los MIME-Types solventó el problema de codificación del que hablaba más arriba.


Por ejemplo, deseamos recibir la página principal de Lobosoft. Para ello, enviamos un mensaje a www4mail@wm.ictp.trieste.it, y en el cuerpo del mensaje incluimos la URL http://www.lobosoft.es. A continuación podemos ver como resultado, el mensaje recibido, y la página adjunta (que aparece mal maquetada, por faltar la hoja de estilos, claro está).



Respuesta del servidor www-mail



Si lo que queremos es obtener una de las imágenes de la página, enviamos un correo a la misma dirección, incluyendo en el cuerpo del mensaje la URL de la imagen en concreto: http://www.lobosoft.es/misarchivos/lobosoft.jpg, que recibiremos adjunta al correo.


Podemos incluir tantas peticiones como deseemos en el correo, y acceder también a servidores de FTP. Hace años, muchos ya, obtuve gracias a este método una increíble colección de ROMS de Spectrum que la Universidad de Valencia alojaba en su FTP, con acceso anónimo para invitados. Eso sí, para la decodificación de los .Z80 y .SNA fue absolutamente necesario contar con la ayuda de un archivo de proceso por lotes (.BAT) .


Y te preguntarás, estimado lector, cómo puede ayudarte algo así hoy día. Podrías pensar que me he dejado llevar por la nostalgia, y en buena parte llevarás razón, pero existen motivos sobrados para conocer recursos como el que presentaba hoy, que desvelaré en la próxima entrega de esta serie.

jueves, 14 de febrero de 2008

El "buscarrutas"

La verdad sea dicha, hace demasiado tiempo que no hago una escapada en condiciones al campo. Hace unos días recordaba la canción Camino Soria porque cuando fuimos a Zaragoza al apoteósico concierto de Héroes del Silencio, el 12 de octubre, quedé prendado de la belleza y la soledad de esa provincia, y me gustaría recorrerla con tiempo suficiente. Incluso en la escapada a Extremadura, en la que pretendía ver algunos dólmenes y bastante más campo, quedó frustrada mi apetencia campestre por culpa del cólico nefrítico cuyos coletazos se cebaron, una vez más, en mi riñón.


Pero bueno, pronto habrá alguna oportunidad más para disfrutar de la naturaleza. Cuando esto ocurra, uno de los aspectos que cualquier senderista debe tener en cuenta es trazar la ruta que desea seguir. Conocer los aspectos más importantes de la misma puede evitarnos problemas y sorpresas desagradables. Para ello, además de poder consultar en las páginas de diversos clubes de interesados en el senderismo y la montaña, de leer libros y estudiar mapas, ahora podemos consultar la WikiLoc , una web a nivel mundial en la que se nos muestran rutas que atraviesan interesantes lugares, y permite ver el trazado y dificultad de la ruta, representarla en Google Earth para ver su perfil, ver fotos que otras personas incluyeron de los lugares que más les impactaron, etc.


Para la próxima excursión me propongo hacer uso de esta herramienta. Y contar la experiencia.

miércoles, 13 de febrero de 2008

Mejora visual en Lobosoft

Hacía días que deseaba instalar algún plugin para Wordpress que permitiese mostrar de una forma más clara el código fuente de las aplicaciones que vayamos desarrollando en el blog. Hace unos días incluía una serie de ejemplos, escritos en distintos lenguajes de programación, que habrían quedado aún más vistosos haciendo uso del plugin iG:Syntax Hiliter. Para muestra, un botón, y qué mejor que un "Hola mundo" recursivo e imparable, en lenguaje C.


[c]
void HolaMundo()
{
printf("Hola mundo\n");
HolaMundo();
}
[/c]

De paso, ya he cambiado también el código del "Hola mundo" en Python de hace un par de días ;)

Security “Distros”

Sin duda, las mejores herramientas para un consultor o especialista en seguridad son las propias herramientas desarrolladas y usadas por los atacantes de nuestros sistemas. Desde el simple pero pontente ping al mítico SATAN (Security Administrator Tool for Analyzing Networks), podemos estudiar cientos de utilidades que nos proporcionan monitorización de nuestra red o acceso a través de puertas traseras y escalada de privilegios, por poner sólo un par de ejemplos.


Los sistemas operativos -nix y, en particular, Linux, son los preferidos de los hackers que intentan acceder de forma ilícita a los sistemas informáticos y, por supuesto, de los administradores de sistemas y responsables de seguridad. La floreciente aparición de distros (distribuciones de Linux, adaptadas para un uso particular y comprendiendo el sistema operativo y las aplicaciones correspondientes al fin que se le quiera dar a esa distribución) para todo, y de los LiveCD que permiten iniciar el sistema operativo en equipos en los que simplemente tengamos acceso al arranque, directamente desde el CD y sin tener que realizar instalación alguna, han propiciado el lanzamiento de varias distribuciones específicas de Linux para consultores de seguridad, con las herramientas más habituales y prácticas para enfrentarse a cualquier problema y realizar una adecuada labor de gestión de la seguridad en los sistemas.


Con el ánimo de reunir e informar a los usuarios sobre este tipo de distros, la web SecurityDistro brinda una serie de artículos y una sección de descarga, donde obtener información y copias de este tipo de distribuciones, que no pueden faltar en el portacedés de ningún administrador o informático forense.

jueves, 7 de febrero de 2008

Hola Mundo con IronPython

Python Logo


Como todo informático de provecho conoce, el "hola mundo" es la prueba de fuego para cualquier lenguaje de programación. Si podemos mandar este mensaje al mundo, de paz, concordia y amistad, todo será posible con el lenguaje en cuestión. Ni las máquinas de Turing, ni formalismos como gramáticas formales, cálculos lambda o computadores cuánticos pueden dar tanto de sí como esa validación universal.


Bromas aparte, hoy he lanzado mi primer hola al mundo a través del CLR de .Net usando además IronPython (una implementación de Python para .Net). Junto a F#, el .Net Framework 3.5 con todas sus novedades y XNA 2.0 tengo diversión (y tenemos temas para el blog) para rato. ¡Que comience la fiesta!


[python]import clr
clr.AddReference("System.Windows.Forms")
import System.Windows.Forms as WinForms
WinForms.MessageBox.Show("Mi hola mundo", "¡Hola mundo!")
[/python]

miércoles, 6 de febrero de 2008

F#

Hablaba hoy mismo con un amigo sobre el disfrute que los nuevos descubrimientos que estamos haciendo en torno al .Net Framework de Microsoft nos están proporcionando. En concreto, le hablaba sobre mis avances con XNA, y él, en un momento determinado, me ha comentado que estaba empezando a ver código escrito en F# (F Sharp), otro de los lenguajes soportados por .Net. Me sonaba haber oído hablar del mismo, pero, ¿qué es realmente F#?


Dicho y hecho, comencé a investigar. Según dicen en el sitio oficial de F#, nos encontramos ante un lenguaje de programación mixto, basado en los paradigmas funcional e imperativo, que toma referentes de los lenguajes OCaml y C#. Así las cosas, no deja de resultar interesante disponer de un lenguaje con esas caracerísticas en nuestro framework de desarrollo preferido. La idea, claro está, es proporcionar el mejor lenguaje para la resolución de un determinado problema: un ebanista no fabrica un mueble con sólo una sierra. Usa la sierra, el escoplo o la lija en función de la tarea que está desempeñando en un momento dado. En este sentido, Microsoft ha ido incorporando al Framework distintos lenguajes que cumplían con los paradigmas más en boga de la programación: orientados a objetos, como C#, VB.Net o Delphi; dinámicos como IronPython o IronRuby; y funcional, ahora, con F#.


Sin duda, desde el mundo científico, el técnico y de las finanzas, donde la programación funcional es realmente la más práctica, y no deja espacio para indeterminaciones, se ha dado un gran paso al contar con un lenguaje de estas características integrado en el .Net Framework. Además, Microsoft ha dado un paso más, permitiendo que el lenguaje pueda ser usado en Mono, la alternativa open source y libre de la comunidad para .Net.


Por lo que he visto el lenguaje da mucho de sí, y habrá que investigarlo a fondo, pero por lo pronto dejo unas muestras de código fuente en las que se puede observar la elegancia de este lenguaje. Para ello, veremos la implementación de un clásico de las matemáticas computacionales, la sucesión de Fibonacci. Recordemos que era una sucesión infinita, en la que sus dos primeros términos eran 0 y 1, y el resto se calculaba como la suma de los dos anteriores: Xi = X(i-1)+X(i-2). Por ejemplo, los 10 primeros términos de la sucesión serían: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34...


Sucesión de Fibonacci




  • F#:




let rec fib n = if n < 2 then 1
else fib (n-2) + fib(n-1)




  • Ruby:




x1,x2 = 0,1; 0.upto(size)
{puts x1; x1 += x2; x1,x2 = x2,x1}




  • C# (2.0):




static int Fibonacci (int x)
{
if (x <= 1)
return 1;
return Fibonacci (x-1) + Fibonacci (x-2);
}




  • C#(3.5):




Func fib = null;
fib = n => n > 1 ? fib(n - 1) + fib(n - 2) : n;




  • brainfuck:



>++++++++++>+>+[
[+++++[>++++++++.--------<-]+<<.>>[
[-]+>[<+>-]++++++<-
[>+++[-]>+>+<<+>>
]<<<
]


La implementación en C# 3.5, usando System.Func y expresiones lambda, junto a la de F# y Ruby... ¡me encantan! El código de brainfuck lo incluyo, claro está, como una mera curiosidad sobre un lenguaje de programación esotérico, pero a la vez con un funcionamiento muy similar al de una máquina de Turing.


Y como nota final: por supuesto, en los lenguajes funcionales, la implementación de muchos problemas debe hacerse de manera recursiva (la equivalencia en programación a la recurrencia matemática), ya que no tienen mecanismos como la iteración (bucles). Esto ocurre en el ejemplo de F# y C# 3.5, lo que les da una sintaxis más cercana a las funciones matemáticas.


En LiteratePrograms.Org se pueden encontrar muchos más ejemplos de algoritmos implementados en diferentes lenguajes. Y si, como curiosidad, queremos ver una serie de benchmarks de eficiencia (en uso de recursos) de distintos lenguajes, podemos hacerlo en The Computer Languaje Benchmarks Game.