Entradas de la categoría ‘Desarrollo’
Código ofuscado

Ofuscación
Las razones que explican este comportamiento son de carácter práctico. Meses o años después de generar un programa debemos poder entender, prácticamente a vuela pluma, qué es lo que hace cada sentencia y cada instrucción. Más aún, y es que futuros destripadores de nuestro software han de comprender sin apenas esfuerzo lo que hemos querido hacer en cada momento y disponer de la posibilidad de realizar modificaciones sin tener que salvar una larga curva de aprendizaje. Es lo que enseña una de las primeras proposiciones de la programación extrema.
Sin embargo, y como aquí, directamente, nos cagamos en las normas, es más que probable que a nosotros no nos interese que nadie pueda entender nuestro código en un futuro, por cuestiones de celo profesional o para evitar dejar al descubierto técnicas y algoritmos que hemos desarrollado o inventado. Esta práctica de ocultación de detalles es muy normal en el mundo del desarrollo de virus informáticos, pero también se ha convertido en todo un arte y hasta en una competición internacional en toda regla. El método se conoce como ofuscación de código.
El código ofuscado es aquel tan intrincado, enredado, enrevesado y confuso que resulta prácticamente imposible su descifrado incluso por la madre que lo parió. Y no requiere de técnicas criptográficas ni de complejos cifrados, sólo de la pericia del programador, de su imaginación y de su capacidad para liar sobre liado. Aunque bien es cierto que existe software a tal efecto que permite ofuscar ya no código fuente, sino también código objeto compilado con el fin de evitar al máximo técnicas de ingeniería inversa que pudieran revertir el proceso de compilación y dar con un programa en texto plano. Pero eso es otra historia.
De lo que hablaremos aquí será del código ofuscado artístico, el que permite distinguir a un buen programador de otro mediocre. Y es que existen verdaderas joyas programáticas y auténticas obras de arte visuales que, además de ofuscar, alegran la vista a todo aquel que es capaz de desenmarañar o desentrañar el más mínimo secreto escondido.
Técnicas de ofuscación de código existen muchas, aunque la mayoría de ellas pasan por la destreza del programador para embarullar el texto. Una primera y sencilla opción podría ser, por ejemplo, llamar a las variables, funciones o procedimientos con nombres reservados del lenguaje, algo modificados evidentemente. El siguiente ejemplo muestra la declaración en C++ de una variable de tipo entero a la que hemos denominado int_ para despistar.
Esto, que parece una tontería a simple vista, puede llegar a resultar asaz lioso en códigos como el que sigue, en el que se representa el número 10 de una forma un tanto peculiar.
(((!(int_-int_)<<!(int_-int_))<<(!(int_-int_)<<!(int_-int_)))|(!(int_-int_)<<!(int_-int_)));El signo de admiración final (!) en C++ es un NOT booleano, y la barra vertical (|) un OR binario. Por su lado, el doble signo de menor que (<<) especifica un AND lógico. Todo este barullo da como resultado el valor 10; ahí es nada. Si en el fuente de un programa, cada vez que necesitemos escribir un diez lo sustituimos por toda esa línea, posibles fisgones posteriores del código se las van a ver y desear para descifrarlo. Eso es ofuscar con un par de pelotas.
Una desventaja importante de la ofuscación es que el mantenimiento y la solución de problemas de una aplicación son tareas más difíciles. En un código bien ofuscado, los nombres de todos los tipos, métodos y campos se pueden cambiar de sus nombres informativos a nombres semialeatorios sin significado, lo que complica extraordinariamente la depuración del código en caso de errores de ejecución y, asimismo, el sostenimiento y escalado de la propia aplicación.
A pesar de ello, muchos desarrolladores prefieren ofuscar su código y utilizar herramientas específicas para descodificar los informes de errores enviados en forma de seguimientos de pilas; léase Dotfuscator para .NET, Proguard para Java o PHP Obfuscator para los script en PHP.
Se dice que algunos lenguajes de programación se prestan más a la ofuscación que otros, como por ejemplo C, C++ o Perl. Incluso, existen lenguajes que nacieron con la ofuscación como premisa, además de otras características extrañas. Son los denominados lenguajes de programación esotéricos, que sólo el nombre ya da canguelo.
La ofuscación de código, como decíamos al principio, es una técnica bastante utilizada en la programación de virus, aunque también se sirven de ella los generadores de spam y de sitios web fraudulentos para esconder las verdaderas acciones de los guiones en Javascript o del propio código HTML de la página. Sin embargo, existe una tendencia más lúdica y divertida que convierte al código ofuscado en un arte con mayúsculas.
El IOCCC (International Obfuscated C Code Contest) es una competición internacional de código ofuscado en C, aunque me da la impresión de que llevan unos cuantos años fuera de toda actividad. Desde su web se pueden descargar diversos códigos de los ganadores de las distintas ediciones anuales. Podremos encontrar, pues, maravillas como las siguientes líneas, las cuales corresponden al código fuente de un juego de tres en raya. Obsérvese la increíble ofuscación prácticamente indescifrable.
a(X){/*/X=- a(X){/*/X=-
-1;F;X=- -1;F;X=-
-1;F;}/*/ -1;F;}/*/
char*z[]={"char*z[]={","a(X){/*/X=-","-1;F;X=-","-1;F;}/*/","9999999999 ",
"int q,i,j,k,X,O=0,H;S(x)int*x;{X+=X;O+=O;*x+1?*x+2||X++:O++;*x=1;}L(n){for(*",
"z[i=1]=n+97;i<4;i++)M(256),s(i),M(128),s(i),M(64),N;X*=8;O*=8;}s(R){char*r=z",
"[R];for(q&&Q;*r;)P(*r++);q&&(Q,P(44));}M(m){P(9);i-2||P(X&m?88:O&m?48:32);P(",
"9);}y(A){for(j=8;j;)~A&w[--j]||(q=0);}e(W,Z){for(i-=i*q;i<9&&q;)y(W|(1<<i++&",
"~Z));}R(){for(k=J[*J-48]-40;k;)e(w[k--],X|O);}main(u,v)char**v;{a(q=1);b(1);",
"c(1);*J=--u?O?*J:*v[1]:53;X|=u<<57-*v[u];y(X);K=40+q;q?e(O,X),q&&(K='|'),e(X",
",O),R(),O|=1<<--i:J[*J-48+(X=O=0)]--;L(q=0);for(s(i=0);q=i<12;)s(i++),i>4&&N",
";s(q=12);P(48);P('}');P(59);N;q=0;L(1);for(i=5;i<13;)s(i++),N;L(2);}",0};
b(X){/*/X=- b(X){/*/X=-
-1;F;X=- -1;F;X=-
-1;F;}/*/ -1;F;}/*/
int q,i,j,k,X,O=0,H;S(x)int*x;{X+=X;O+=O;*x+1?*x+2||X++:O++;*x=1;}L(n){for(*
z[i=1]=n+97;i<4;i++)M(256),s(i),M(128),s(i),M(64),N;X*=8;O*=8;}s(R){char*r=z
[R];for(q&&Q;*r;)P(*r++);q&&(Q,P(44));}M(m){P(9);i-2||P(X&m?88:O&m?48:32);P(
9);}y(A){for(j=8;j;)~A&w[--j]||(q=0);}e(W,Z){for(i-=i*q;i<9&&q;)y(W|(1<<i++&
~Z));}R(){for(k=J[*J-48]-40;k;)e(w[k--],X|O);}main(u,v)char**v;{a(q=1);b(1);
c(1);*J=--u?O?*J:*v[1]:53;X|=u<<57-*v[u];y(X);K=40+q;q?e(O,X),q&&(K='|'),e(X
,O),R(),O|=1<<--i:J[*J-48+(X=O=0)]--;L(q=0);for(s(i=0);q=i<12;)s(i++),i>4&&N
;s(q=12);P(48);P('}');P(59);N;q=0;L(1);for(i=5;i<13;)s(i++),N;L(2);}
c(X){/*/X=- c(X){/*/X=-
-1;F;X=- -1;F;X=-
-1;F;}/*/ -1;F;}/*/En otro orden, encontramos programadores que, además de ofuscar su software, realizan auténticas obras de arte ASCII con el código. Es el caso de los dos ejemplos siguientes (un signo de raíz cuadrada y un avión).
int l;int main(int o,char **O,
int I){char c,*D=O[1];if(o>0){
for(l=0;D[l ];D[l
++]-=10){D [l++]-=120;D[l]-=
110;while (!main(0,O,l))D[l]
+= 20; putchar((D[l]+1032)
/20 ) ;}putchar(10);}else{
c=o+ (D[I]+82)%10-(I>l/2)*
(D[I-l+I]+72)/10-9;D[I]+=I<0?0
:!(o=main(c/10,O,I-1))*((c+999
)%10-(D[I]+92)%10);}return o;}
#include <math.h>
#include <sys/time.h>
#include <X11/Xlib.h>
#include <X11/keysym.h>
double L ,o ,P
,_=dt,T,Z,D=1,d,
s[999],E,h= 8,I,
J,K,w[999],M,m,O
,n[999],j=33e-3,i=
1E3,r,t, u,v ,W,S=
74.5,l=221,X=7.26,
a,B,A=32.2,c, F,H;
int N,q, C, y,p,U;
Window z; char f[52]
; GC k; main(){ Display*e=
XOpenDisplay( 0); z=RootWindow(e,0); for (XSetForeground(e,k=XCreateGC (e,z,0,0),BlackPixel(e,0))
; scanf("%lf%lf%lf",y +n,w+y, y+s)+1; y ++); XSelectInput(e,z= XCreateSimpleWindow(e,z,0,0,400,400,
0,0,WhitePixel(e,0) ),KeyPressMask); for(XMapWindow(e,z); ; T=sin(O)){ struct timeval G={ 0,dt*1e6}
; K= cos(j); N=1e4; M+= H*_; Z=D*K; F+=_*P; r=E*K; W=cos( O); m=K*W; H=K*T; O+=D*_*F/ K+d/K*E*_; B=
sin(j); a=B*T*D-E*W; XClearWindow(e,z); t=T*E+ D*B*W; j+=d*_*D-_*F*E; P=W*E*B-T*D; for (o+=(I=D*W+E
*T*B,E*d/K *B+v+B/K*F*D)*_; p<y; ){ T=p[s]+i; E=c-p[w]; D=n[p]-L; K=D*m-B*T-H*E; if(p [n]+w[ p]+p[s
]== 0|K <fabs(W=T*r-I*E +D*P) |fabs(D=t *D+Z *T-a *E)> K)N=1e4; else{ q=W/K *4E2+2e2; C= 2E2+4e2/ K
*D; N-1E4&& XDrawLine(e ,z,k,N ,U,q,C); N=q; U=C; } ++p; } L+=_* (X*t +P*M+m*l); T=X*X+ l*l+M *M;
XDrawString(e,z,k ,20,380,f,17); D=v/l*15; i+=(B *l-M*r -X*Z)*_; for(; XPending(e); u *=CS!=N){
XEvent z; XNextEvent(e ,&z);
++*((N=XLookupKeysym
(&z.xkey,0))-IT?
N-LT? UP-N?& E:&
J:& u: &h); --*(
DN -N? N-DT ?N==
RT?&u: & W:&h:&J
); } m=15*F/l;
c+=(I=M/ l,l*H
+I*M+a*X)*_; H
=A*r+v*X-F*l+(
E=.1+X*4.9/l,t
=T*m/32-I*T/24
)/S; K=F*M+(
h* 1e4/l-(T+
E*5*T*E)/3e2
)/S-X*d-B*A;
a=2.63 /l*d;
X+=( d*l-T/S
*(.19*E +a
*.64+J/1e3
)-M* v +A*
Z)*_; l +=
K *_; W=d;
sprintf(f,
"%5d %3d"
"%7d",p =l
/1.7,(C=9E3+
O*57.3)%0550,(int)i); d+=T*(.45-14/l*
X-a*130-J* .14)*_/125e2+F*_*v; P=(T*(47
*I-m* 52+E*94 *D-t*.38+u*.21*E) /1e2+W*
179*v)/2312; select(p=0,0,0,0,&G); v-=(
W*F-T*(.63*m-I*.086+m*E*19-D*25-.11*u
)/107e2)*_; D=cos(o); E=sin(o); } }Este último fue el ganador del IOCCC de 1998, y, precisamente, el programa es un inteligente y compacto simulador de vuelo.
Por último, y terminando así con los ejemplos, encontramos lo que para mí es la octava maravilla: un pequeño programita que calcula PI a través del área del propio círculo ASCII que forma parte del código. Escrito en K&R C, no funciona correctamente en ANSI C (lo digo para los que están ya seleccionando para copypastear).
int F=00,OO=00;main(){F_OO();printf("%1.3f\n",4.*-F/OO/OO);}F_OO()
{
_-_-_-_
_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_
_-_-_-_
}
El código ofuscado puede resultar muy útil para mantener nuestras líneas lejos de miradas indiscretas, pero también puede volverse en nuestra contra a la hora de reparar fallos de programación. Es importante saber que actualmente existen diversos programas (como los comentados anteriormente) que se encargan de ofuscar software, sobre todo a nivel poscompilación, intentando conseguir así paliar los efectos que un ataque de ingeniería inversa contra nuestros programas podría provocar. Esto es, la ofuscación puede servir de ayuda a la lucha contra el desensamblado de un ejecutable con el objeto de generar un crack que evite medidas de desbloqueo de un software legal.
Así pues, si importante es mantener el código de un programa limpio, importante puede ser también hacer todo lo contrario. Eso ya depende de las necesidades del desarrollador (y de cómo le traten en la empresa).
Lo impensable en 4 kas

Fotograma intro 4K
La demoscene es una subcultura informática que nace en la época de los 8 bits y se populariza en los años de los 16 bits, llegando hasta nuestros días prácticamente sin desvirtuar en lo que a la esencia se refiere. Una demo es un pequeño pedazo de software ejecutable que incluye música, imágenes y animación. Su origen se remonta a la época del Spectrum y el Commodore 64, cuando los cracker de juegos y programas introducían sus perlas digitales en el software reventado a modo de firma introductoria antes de la ejecución. Aquella moda se convirtió en competición, y los jóvenes expertos pugnaban por desarrollar una intro mejor y más impresionante que sus contrincantes (amigos y conocidos, normalmente). Un estilo a las batallas de gallos del mundo de rap, en las que la competición consiste en superar al adversario con todo el arsenal disponible, pero, una vez terminada la disputa, el enemigo se convierte de nuevo en compañero.
En aquel entonces, el ingenio había de prevalecer sobre la capacidad en bytes, porque esta era muy limitada, y la necesidad de hacer algo cada vez más grande se imponía en cada batalla. De allí llegan a nuestros días las competiciones con límites de capacidad en todas y cada una de las parties informáticas del mundo. Competiciones que pueden ser de gráficos rápidos en 2D, en 3D, grandes demos audiovisuales, intros de 64 KB o intros de 4 KB, entre otras. En principio, una intro es un derivado de una demo con la particularidad de que la secuencia de imágenes se repite continuamente, debido, por supuesto, a las limitaciones técnicas que se les requiere.
El mundo de la intros de 64 KB es el que más llama la atención al extraño o visitante, ya que suelen ser animaciones con luces, sombras y texturas bastante conseguidas para tener que ocupar tan poco espacio en disco. Sin embargo, la intro 4K sigue siendo la niña bonita de los desarrolladores y expertos, porque implica un reto que es dechado de imaginación, ingenio, creatividad y conocimiento, sólo apto para sufridores extremos dispuestos a compilar cientos de veces hasta que aquello entre en 4.096 bytes, aunque sea con calzador y a cabezazos. Actualmente existen competiciones también de 1 KB, 256 bytes, 64 bytes y hasta de 32 bytes, sin embargo las 4K tienen un algo que enamora a propios y extraños.
Una intro 4K, pues, es una demo que se caracteriza por una limitación en el tamaño máximo permitido para el ejecutable, que puede contener código, modelos, texturas, animaciones y música. Por lo general se trata de una competición por y para los coder más avezados de la scene, ya que en 4 KB es imposible acoplar imágenes JPEG o sonidos MID (y prácticamente texturas tampoco), por lo que tanto música, animación, como contenido gráfico deberá estar codificado a golpe de tecla; es la matemática pura hecha obra de arte.
NOTA: A continuación se muestra el vídeo del resultado de una intro 4K. Todos los vídeos que aparezcan en esta entrada se corresponden con ejecutables binarios de 4 kilobytes, pero preferimos distribuir directamente sus grabaciones en formato videotubo para evitar problemas de compatibilidad por falta de librerías de proceso gráfico o por diferencia de sistemas operativos.
Las intros de 4 KB son, ante todo, un ejercicio de programación extrema y empleo masivo de técnicas de compresión. Además, y como excepción a la regla general de la demoscene, con las intros 4K se relajan las normas morales en cuanto a uso de recursos externos se refiere. Es decir, en las intros 4K, la demoscene es relativamente flexible y permite que la demo haga uso de librerías externas en el borde de la estandarización o, incluso, de datos externos (estándares en los sistemas operativos pertinentes) como muestras de sonido o fuentes; aunque esto último no está muy bien visto por algunos scenner. Es cuestión de cada cual juzgar las intros teniendo esto en cuenta, o no, como criterio de decisión. En cualquier caso, la demoscene acepta el hecho con normalidad. Por otra parte, este comportamiento, a priori contrario a la ortodoxia scenner, no sólo ha permitido que las intros sigan evolucionando (y por ende, sorprendiendo), sino que además ha desencadenado nuevas técnicas y ha motivado ingeniosas estrategias y algoritmos, basados hoy día en cualquier tipo de plataforma, sea MS-DOS, Windows, Linux, Mac OS, las antiguas máquinas de 8 y 16 bits o las consolas de videojuegos más modernas.
Una intro 4K se construye básicamente en lenguaje C plano, pese a la leyenda urbana que dice que el ensamblador es el idioma único para entenderse con las demos. Puede que en su día lo fuera, y es cierto que en algunos grupos scenner tiene aún un peso importante, pero mucho de eso pasó ya a la historia. El buen arte de programación del coder es indispensable, pues el código debe estar lo suficientemente optimizado para generar una aplicación de sólo 4 KB y de aspecto sorprendente. Las matemáticas más complejas, la geometría fractal, la física de la animación, la trigonometría o la síntesis musical, entre otras materias, deben ser asignaturas superadas por el desarrollador (o desarrolladores de un grupo), o no podrá aspirar a un puesto decente en la competición. Librerías como OpenGL o Direct3D, o lenguajes como GLSL no pueden albergar secretos.
A la hora de programar una 4K es aconsejable seguir algunas directrices que indican los expertos, como, por ejemplo, modular el código. Esto, que parece un contrasentido (cuanto más compacto sea el fuente, menos ocupará), es fácilmente explicable, ya que los programas de compresión que se aplican posteriormente a los ejecutables funcionan mejor si el código de la intro está bien estructurado y separado en funciones y demás. Otros trucos, por ejemplo, consisten en utilizar los mínimos parámetros (no opcionales) de las funciones, evitar la liberación de recursos y el control de excepciones y valores de entrada, redondear valores con pocos decimales, conocer los estados por defecto o configurar correctamente las funciones del compilador. La obsesión por el ahorro de espacio se convierte en una paranoia.
Hoy en día existen numerosas herramientas y recursos gratuitos creados a propósito para los scenner que codifican intros 4K. Desde software de compresión (como Crinkler), sintetizadores de música (si no te apetece desarrollar el tuyo, o no sabes, como 4k synth) o completos frameworks de desarrollo (como los de IQ). Además de ello, están a disposición de todo el que lo necesite sitios web con mucha información y recursos, como el español escena.org, el wiki IN4K o, sobre todo, pouet.net, algo así como la Biblia de la demoscene, la base de datos mundial de scenner, grupos, concentraciones y trabajos publicados. En esta sección de publicación de producciones, podemos encontrar infinidad de demos e intros desarrolladas en cualquier modalidad y para cualquier plataforma. Al acceder a cada una de ellas, tendremos la posibilidad de descargar su ejecutable original o, en muchos casos, de visualizarla vía YouTube (como los ejemplos en este post), ya que algunas producciones pueden no llegar a llevarse bien con la configuración de nuestro equipo. El código fuente de muchas demos ha sido liberado y es posible descargarlo también.
Con respecto a los scenner programadores y a sus intros, varios han sido quienes han descollado a nivel mundial. Grandes hitos internacionales fueron las intros Parsec (primer premio en la Breakponit de 2005) o Micropolis (3º en el Assembly 2004), pues representaron un punto de inflexión muy representativo en su época. En el panorama nacional, el grupo propulsor de la categoría 4K fue Fuzzion, que desarrolló innumerables intros de calidad como Polar Field (primer premio en el Euskal Encounter de 2006 y nominada a los Scene.org Awards) o Frogzilla (también primer premio en el Euskal Encounter del año 2004). También Collapse y NecroStudios han sido buenos ejemplos locales de desarrollo genial, con intros como Katedra o Red Trip. Otros grupos, como r g b a, Software Failure (Ham’s Cyberneocortical) o Nocturns han hecho incursiones puntuales en la categoría.
Pero, sin duda, si algún scenner local ha sobresalido sobre el resto de los demás, ese es IQ, un donostiarra que para algunos es el verdadero genio de la lámpara dentro de la demoscene. En el año 2009, ganó el primer premio en la Breakpoint con una intro que dejó a media escena mundial con la boca abierta durante un buen rato. La obra de arte, llamada Elevated, podría considerarse, probablemente, como la mejor intro 4K de la historia sin miedo a equivocarnos (la podemos ver a continuación). Imaginar que esta animación sólo ocupa 4 kilobytes y está generada exclusivamente a base de algoritmos matemáticos es suficiente para darnos cuenta por qué se rumoreaba que a su autor le andaba rondando Pixar hace bien poco.
La demo-escena es una cueva del underground informático en el que se encierran los actuales magos del arte rupestre digital. ¿Quieres entrar? No es sencillo, pero tampoco imposible. Decántate por imagen o sonido, y estudia, recopila datos, desmenuza producciones ajenas, lee, aprende de los demás y ten mucha, mucha paciencia. Pretende primero grandes demos sin limitaciones y deja las comprimidas para el final. Llegar a dominar las 4K se encuentra en el terreno de unos pocos elegidos.
Utilizando el algoritmo Chudnovsky y Visual Basic para calcular los catorce primeros dígitos decimales de Pi sin despeinarse (y otros chismes y cotilleos varios)

Pi
3,14 (en el colegio) o a 3,14159 (en la universidad). Conocido universalmente como 3,1416, π ha sido aproximado a lo largo de la historia hasta una exactitud de 5 billones de decimales, esto hace bien poquito. Y es que los matemáticos y los informáticos no tienen otra cosa que hacer en este mundo que perder el tiempo intentando encontrar un decimal nuevo para hacerse famosos y salir en el Muy Interesante y en la Wikipedia. Como si no supieran que esta carrera no tiene fin, y que pasado mañana saldrá a la palestra un chino mandarino o un japonés loco que encontrará el decimal número 6 billones; como si lo estuviera viendo.
Para los estudiantes del bachillerato actual diremos que π señala las veces en que el diámetro de un círculo cabe en su circunferencia. Ahora sí, ¿verdad? Hacemos un redondel con una cuerda y la estiramos en el suelo. Luego marcamos los diámetros sobre la cuerda y comprobamos que nos caben 3 y un poquito más. Eso es π. El siguiente GIF animado es totalmente esclarecedor.

Explicación gráfica de Pi muy sencilla de entender
En fin, nos unimos al carro de aproximaciones de π, pero no para intentar descubrir el decimal seiscientos trillones, sino para conocer el algoritmo Chudnovsky, uno de los más modernos métodos de calcular decimales de π. Algoritmos para este menester ha habido infinidad de ellos desde que el mundo es mundo, empezando por el de Arquímedes y pasando por los de Euler, Newton o Gauss (sí, el de las campanas).
El algoritmo Chudnovsky, descubierto por los hermanos David y Gregory Chudnovsky, matemáticos ucranianos, parece ser el más empleado en los cálculos de alta precisión de dígitos de π a comienzos de este siglo XXI en el que nos encontramos. Se fundamenta en una fórmula del hindú Ramanujan e implementa una serie de convergencia rápida siguiendo una serie hipergeométrica. Su fórmula es la siguiente:

Algoritmo matemático Chudnovsky
Como se puede comprobar, no es más que un sumatorio sobre k desde 0 hasta infinito (∞), donde se hacen una barbaridad de operaciones en función de k en cada iteración. Cada término de esta fórmula añade 14 decimales exactos al valor calculado de π; k es una proporción entre la precisión en decimales que necesitemos calcular y el valor límite de 14. Es una fórmula incluida en el famoso software Mathematica, de uso común en el ámbito científico.
Lo que se detalla a continuación es un pequeño código en Visual Basic que nos permite extraer el valor exacto de π con sus catorce primeros decimales haciendo uso de la fórmula de los hermanos Chudnovsky. Es muy sencillo de entender, ya que sólo sigue paso a paso el algoritmo. Destacar únicamente la función auxiliar Factorial para calcular los factoriales requeridos.
Dim k As Long
Dim numeroPI As Double
Dim Numerador As Double, Denominador As Double
Dim Precision As Double, Limite As Double
k = 0: numeroPI = 0
Precision = 14
Limite = (Precision + 3) / 14
Do While k < Limite
Numerador = 0
Denominador = 0
Numerador = ((-1) ^ k) * Factorial(6 * k) * (13591409 + (545140134 * k))
Denominador = Factorial(3 * k) * (Factorial(k) ^ 3) * (640320 ^ ((3 * k) + (3 / 2)))
numeroPI = numeroPI + (Numerador / Denominador)
k = k + 1
Loop
numeroPI = 12 * numeroPI
numeroPI = 1 / numeroPI
Debug.Print FormatNumber(numeroPI, 14)
End Sub
Private Function Factorial(numFactorial As Long) As Double
Dim i As Long, TempFactorial As Double
TempFactorial = 1
For i = 1 To numFactorial
TempFactorial = TempFactorial * i
Next i
Factorial = TempFactorial
End Function
Que nadie intente calcular más de catorce decimales porque precisamente ese es el límite de las variables de doble precisión en Visual Basic. Eso sí, se puede extraer un número inferior alterando el valor de la variable Precision.
Los hermanos Chudnovsky, actualmente, residen en Estados Unidos y, además de por su habilidad en la construcción de supercomputadores caseros, son conocidos por la estrecha relación laboral que ambos mantienen, llegando a definirse ellos mismos como “un único matemático ocupando dos cuerpos”. Esta colaboración también está marcada, en cierta medida, por la enfermedad de tipo muscular que sufre Gregory, que lo hace en ocasiones dependiente de su hermano David. De este último se ha llegado a decir que es el mejor matemático vivo de la historia.
Los cerebritos calculines continuarán su gesta de intentar llegar al final del número π, hasta el último decimal que lo convierta en un número irracional transcendente de valor concreto. O quizás tengan razón aquellos que aseguran que los decimales de π no se acabarán nunca, y que dicen que es un número tan complejamente apasionante que, por ejemplo, todos los números de teléfono del mundo se pueden encontrar escondidos en la secuencia decimal de π, porque sus dígitos parecen estar repartidos aleatoriamente y no construidos de una forma particular (encontrándose entre sus infinitos guarismos cualquier secuencia posible). O es probable que todos ellos tengan razón y ninguno de ellos la tenga, aunque seguramente la longitud de π acabará siendo bastante mayor que el título de este post (aunque parezca mentira).
Lo que está claro es que π es, para muchos, un número mágico donde buscar mensajes ocultos, y para todo el mundo un valor importantísimo que permite construir carreteras y barcos, entre otras muchas cosas. Su número de decimales importa poco a niveles prácticos hoy en día, porque sería una locura realizar cálculos con tal nivel de exactitud, además de una estupidez supina. Pero, por lo menos, vamos observando nuestra amplia evolución desde hace un par de miles de años, cuando se deducía de la mismísima Biblia que el valor de π era simplemente igual a 3; en Primera de Reyes, 7-23, dice literalmente:
Hizo fundir asimismo un mar de diez codos de un lado al otro, perfectamente redondo; su altura era de cinco codos, y lo ceñía alrededor un cordón de treinta codos.
Por último, y ya que estamos en ello, recomendar desde aquí la película “Pi, fe en el caos“, una obra de arte geek y profundamente paranoica y demente, pero que todo buen friqui tecnológico debe visionar. Especial atención a sus múltiples fallos, comenzando desde el principio por el más garrafal de todos.
EDITANDO ANDO (17/09/2010): Se acaba de superar del récord de decimales de π calculados mencionado en esta entrada. Además ha sido a lo bestia, porque de 5 billones hemos pasado a 2.000 billones; casi na. El mérito es para un currela de Yahoo que se ha aprovechado de la infraestructura tecnológica de su empresa para tal menester. Así cualquiera.
Concurrencia optimista en bases de datos

Red de datos
Para solventar esta traba a la hora de actualizar una base de datos se pueden esgrimir dos recursos o modelos: la concurrencia pesimista y la concurrencia optimista. Los objetos que manipulan datos en los distintos lenguajes de programación están preparados para manejar ambas técnicas, por lo que no nos va a resultar nada complicado aplicar una u otra. Nosotros apostamos desde siempre por la concurrencia optimista, sobre todo en determinados entornos, pero explicaremos brevemente en que consisten los dos procedimientos.
La concurrencia pesimista implica bloquear filas, o registros, en el origen de datos para impedir que otros usuarios modifiquen la información, de tal forma que el usuario actual resulte afectado. En un modelo pesimista, cuando un usuario realiza una acción que hace que se aplique un bloqueo, otros usuarios no pueden realizar acciones que entrarían en conflicto con ese bloqueo hasta que el propietario del mismo lo libere. Este modelo se utiliza principalmente en aquellos entornos en los que hay mucha contención de datos, de manera que el costo de protegerlos mediante bloqueos es menor que el costo de deshacer transacciones si se producen conflictos de concurrencia.
La concurrencia pesimista puede resultar útil en ambientes donde los tiempos de bloqueo son cortos, por ejemplo la actualización automática de registros, según determinadas reglas, mediante software. Sin embargo, es una técnica que consume recursos del servidor, necesita de una conexión persistente con el gestor de datos y no resulta nada escalable cuando los usuarios, interactuando con los datos, hacen que los registros queden bloqueados durante períodos de tiempo relativamente largos (mientras se modifican las líneas de una factura, por ejemplo).
Por el contrario, utilizando el sistema de concurrencia optimista no se bloquean filas cuando se lee, sino que se realizan copias locales desconectadas de los datos y, una vez se hayan editado, se vuelca la nueva información sobre la base de datos original. En este caso se produce el problema al que aludíamos al principio, ya que en el tiempo que nosotros hemos estado modificando los datos, otro usuario ha podido acceder al registro y haber realizado sus propias modificaciones. Es, entonces, la aplicación informática la que debe determinar si la información se han modificado o no desde que se leyó. Esta técnica, aunque parezca más farragosa de implementar, mejora el rendimiento del sistema y la velocidad de acceso de todos usuarios, ya que el origen de datos no se encuentra nunca bloqueado y puede servir información continuamente y bajo demanda.
En el momento en que un equipo intente modificar determinados registros y detecte que han sido ya modificados con respecto a la información original que tenía desde que se leyó, en el modelo de concurrencia optimista se considera que hay una infracción. La pericia del programador consistirá en detectar dichas infracciones y saber actuar a tal efecto, dependiendo del proceso que se esté realizando y de las circunstancias puntuales. Esto es, una infracción puede resolverse sobrescribiendo los nuevos datos o manteniendo las modificaciones sin realizar. En función de las características del proyecto y de las necesidades del cliente habrá que hacer una u otra cosa.
Vamos a ver un ejemplo práctico haciendo uso de una pequeña tabla de tres campos y un único registro. La tabla original podría ser como la siguiente:
| IdCliente | Apellido | Nombre |
| 101 | Martínez | Cris |
Imaginemos que un Usuario_1 lee la fila anterior de la base de datos a las 12:00 AM. Veamos una representación gráfica de los tres valores que nos ocupan: el valor original (valor cuando se leyó el registro), el valor actual (el que modifica Usuario_1 en local) y el valor en la base de datos (el valor que se encuentra registrado en la tabla).
| Nombre de columna | Valor original | Valor actual | Valor en la base de datos |
| IdCliente | 101 | 101 | 101 |
| Apellido | Martínez | Martínez | Martínez |
| Nombre | Cris | Cris | Cris |
En este caso los tres valores coinciden, porque Usuario_1 todavía no ha hecho ninguna modificación, simplemente ha extraído la información.
A las 12:01 AM, un nuevo Usuario_2 recurre al servidor para leer la misma fila, y a las 12:03 AM edita el campo Nombre (cambia “Cris” por “Cristina”) y actualiza la base de datos. Nuestra representación visual del baile de cadenas de texto sería ahora la que sigue:
| Nombre de columna | Valor original | Valor actual | Valor en la base de datos |
| IdCliente | 101 | 101 | 101 |
| Apellido | Martínez | Martínez | Martínez |
| Nombre | Cris | Cristina | Cris |
La actualización se realiza correctamente porque los valores contenidos en la base da datos en el momento de renovar la fila coinciden con los valores originales de tenía Usuario_2 (“Cris”, en la base de datos, es igual que el dato “Cris” del momento de la lectura); no existe ninguna infracción para Usuario_2.
Vamos a imaginar ahora que Usuario_1 termina de realizar sus modificaciones a las 12:05 AM (cambia “Cris”, su lectura, por “María Cristina”). Veamos la representación:
| Nombre de columna | Valor original | Valor actual | Valor en la base de datos |
| IdCliente | 101 | 101 | 101 |
| Apellido | Martínez | Martínez | Martínez |
| Nombre | Cris | María Cristina | Cristina |
Al intentar actualizar se va a encontrar con una infracción de la concurrencia optimista, ya que el valor actual de la base de datos (“Cristina”) no coincide con el valor que él esperaba para ese campo (“Cris”) porque Usuario_2 lo había modificado previamente. Es ahora el momento en el que hay que tomar la decisión de sobrescribir los cambios realizados o, por el contrario, cancelar la actualización. Como antes decíamos, la elección de una u otra acción dependerá de la situación en concreto y de las querencias del cliente.
Existen varias técnicas para determinar una infracción de concurrencia optimista a la hora de actualizar una base de datos. Una de ellas consiste en incluir una columna de marca de tiempo en la tabla. Las bases de datos suelen ofrecer funcionalidad de marca de tiempo que puede utilizarse para identificar la fecha y la hora en que se actualizó el registro por última vez. Mediante esta técnica, decimos, se incluye una columna de marca de tiempo en la definición de la tabla y, siempre que se actualiza el registro, se actualiza la marca de tiempo, de manera que queden reflejadas la fecha y la hora actuales. Al hacer una prueba para ver si hay infracciones de la concurrencia optimista, la columna de marca de tiempo se devuelve con cualquier consulta del contenido de la tabla. Cuando se intenta realizar una actualización, se compara el valor de marca de tiempo de la base de datos con el valor de marca de tiempo original contenido en la fila modificada. Si coinciden, se realiza la actualización y se edita la columna de marca de tiempo con la hora actual, con el objeto de reflejar la actualización. Si no coinciden, se ha producido una infracción de la concurrencia optimista.
Otra técnica para probar si hay alguna infracción relacionada con la concurrencia optimista consiste en comprobar que todos los valores de columna originales de una fila siguen coincidiendo con los existentes en la base de datos.
Veamos la siguiente consulta SQL contra una base de datos:
SELECT Col1, Col2, Col3 FROM Tabla1
UPDATE Table1 Set Col1 = @NuevoValorCol1,
Set Col2 = @NuevoValorCol2,
Set Col3 = @NuevoValorCol3
WHERE Col1 = @ViejoValorCol1 AND
Col2 = @ViejoValorCol2 AND
Col3 = @ViejoValorCol3 Lo que se hace es seleccionar (SELECT) los campos, o columnas, que se van a modificar para, después, actualizar (UPDATE), con los nuevos valores (@NuevoValorColX), todos aquellos donde (WHERE) los valores originales (@ViejoValorColX) coincidan con los valores actuales en base de datos (ColX).
La teoría es sencilla, pero la implementación puede llegar a complicarse bastante, no por la técnica en sí, sino por la obligación de tomar una decisión en cada uno de los momentos. Será ya la intuición del desarrollador la que indique qué solución tomar en cada caso de infracción. Lo que sí debe quedar claro es que, excepto en determinadas y muy puntuales ocasiones, la concurrencia optimista siempre debe preferirse por encima de la pesimista. Es mejor resolver mal una infracción (cosa que puede corregirse a posteriori) que mantener una red de datos a un 40% de su capacidad total de gestión por acciones de bloqueo tras bloqueo, lentitud, falta de escalabilidad y desidia del usuario que es incapaz de trabajar en esas condiciones.
Iniciar a los niños en el mundo de la programación informática con Scratch

Scratch
Scratch es una herramienta gratuita para que los más pequeños de la casa se inicien en el cruel mundo del desarrollo de software (sí, cruel he dicho). Si me apuras, los mayores que no tengan ni repajolera idea de escribir un programa informático podrían hacer uso también de ella para sus primeros pinitos, aunque en principio el software está diseñado para los niños entre 6 y 16 años. De todas las herramientas que conozco para iniciar a los pequeños en la programación, esta es la que más me ha gustado con diferencia por su facilidad de uso, su interfaz intuitiva y, sobre todo, porque su curva de aprendizaje tiene muy poco de curva y mucho de aprendizaje. (Por cierto, aunque parezca mentira, esto no es un post patrocinado ni nada por el estilo).
Scratch se basa en scripts o guiones de acciones por lotes que se asocian a objetos (sprites) o escenas en pantalla. Los sprites son pequeños elementos visuales que representan una imagen o icono, no en vano Scratch está eminentemente preparado para que los niños aprendan creando una historia interactiva, un juego o una animación, es decir, que aprendan jugando. Cada objeto es susceptible de tener diversos disfraces o personalizaciones, así como sonidos asociados, lo que permite variar el objeto en función de determinadas circunstancias. Esto nos recuerda a la propiedad de los personajes de cualquier juego de cambiar su apariencia dependiendo de la dirección en la que caminen, si saltan, corren o pierden una vida.

Pantalla principal de Scratch
La característica más importante de Scratch es la falta de necesidad de introducir una sola línea de código para generar un programa. La aplicación funciona por medio de los denominados bloques, agrupados en paletas según sus características. Un bloque es una pieza o elemento que encierra una acción que puede ser de apariencia, de sonido, de movimiento, de decisión, de control, etcétera. Los bloques se arrastran de la Paleta de bloques al Panel de script, creando pilas o conjuntos de bloques que constituyen en sí mismos pequeños programas o subrutinas del programa general al que pertenecen.
Por ejemplo, en la siguiente imagen se muestra un script que hará moverse el objeto formando un cuadrado en cinco ocasiones consecutivas. Entre cada acción se ha insertado un retardo de un segundo para apreciar bien los movimientos; además, el disparador del comienzo de la acción es la pulsación de la barra espaciadora.

Script en Scratch
Como se puede apreciar, Scratch es sumamente sencillo de manejar. Simplemente habrá que ir arrastrando bloques de acciones para crear programas que afectarán a un objeto o a una escena completa. Cada objeto y cada escena tienen sus propios grupos de bloques que funcionan de manera independiente, ejecutando cada tarea en el momento preciso.
Scratch dispone de bloques de acciones totalmente engarzados con la estructura de la programación “adulta” actual orientada a objetos, y ese es su mejor medio de presentación para el aprendizaje. Disponemos de estructuras de control, repeticiones y bucles, sentencias condicionales, empleo de variables globales y locales, manejo de cadenas de texto, listas o matrices unidimensionales de objetos, operadores aritméticos y booleanos, comparaciones, control de eventos, etcétera. Es más que posible desarrollar cualquier programa sencillo con Scratch, además de las animaciones y juegos a los que está orientado. Para estos últimos también gozamos de características implementadas de fábrica como el movimiento de personajes, el rebote de objetos o el control de colisiones.
Además de todo ello, Scratch tiene una característica bastante interesante, que es la de subir al sitio web de la aplicación nuestras últimas creaciones para compartirlas con toda la comunidad (bajo licencia Creative Commons); y todo ello de una manera automática. Estas aplicaciones en línea se reproducen sobre un applet de Java, sin embargo, para ejecutar los programas en local deberemos tener instalada la herramienta en sí, ya que Scratch no dispone de un compilador al uso que nos permita generar un archivo ejecutable compatible con nuestro sistema operativo.
Y para los más friquis también tenemos importantes noticias, ya que Scratch es capaz de conectar con los productos LEGO WeDo y dispone de bloques de acciones específicamente diseñados para interactuar con los motores de tus diseños de robótica. Simplemente habremos de conectar nuestro robot LEGO con el ordenador vía USB y generar el programa correspondiente desde Scratch con la misma facilidad que hemos comentado anteriormente.
En el siguiente vídeo (en inglés) se puede ver el desarrollo de una aplicación en Scratch que maneja un robot de LEGO WeDo con forma y movimientos de portero de fútbol.
¿Te he convencido ya? ¿Todavía no? Esto de Scratch parece salido de la mente de un padre rarito que quería que su hijo aprendiera a programar y le diseño una herramienta, ¿verdad? Pues espera a oír leer lo que sigue.
Scratch es una herramienta multilingüística, gratuita y de software libre creada por el grupo Lifelong Kindergarten Group del MIT Media Lab, el departamento de tecnología y multimedia del Instituto Tecnológico de Massachusetts (MIT), en Estados Unidos. Está disponible para sistemas Windows, Linux y Mac OS X (qué pena de Solaris, pero nadie es perfecto), y es un proyecto dirigido por Mitchel Resnick y financiado por la National Science Foundation (Fundación Nacional de Ciencia) estadounidense, Microsoft, Intel, Nokia, Iomega y los consorcios de investigación del MIT Media Lab, además de otros organismos, universidades y empresas privadas.
Es uno de los softwares educativos más reconocidos a nivel mundial y especialmente recomendado por el Observatorio Tecnológico del Ministerio de Educación español. Se utiliza en todo el mundo en muchos entornos diferentes: escuelas, museos, centros de aprendizaje, hogares, ayuntamientos…
El 15 de diciembre de 2009, la comunidad web de Scratch contaba con más de 408.227 miembros registrados (95.033 de ellos habían colgado sus proyectos), con un total de 796.359 proyectos compartidos por la comunidad. El sitio web obtiene cerca de 7.000.000 de páginas vistas al mes. En el año 2010, la web de Scratch cuenta con más de un millón de proyectos alojados y compartidos (código fuente incluido). Además, cada cierto tiempo se celebra el Scratch Design Studio, un evento basado en desafíos que fomentan la creación y el intercambio de ideas y proyectos. Asimismo, disponen de una comunidad en línea exclusiva para educadores denominada ScratchEd.
El éxito de la herramienta es tal que se ha desarrollado incluso algún que otro mod, o modificación alternativa derivada del original, basado en el código fuente de Scratch y que agrega nuevos bloques de funciones o cambios en la interfaz gráfica, siendo los más relevantes BYOB (programado por Jeans), Panther (por Panther Team) y Streak (de Billyedward).
¿Cómo se te queda el cuerpo ahora? La verdad es que es la herramienta ideal a la disposición de niños y adolescentes para iniciarse en el mundo del desarrollo de software. Y hablamos de iniciarse, por lo que nadie espere conexión con bases de datos distribuidas, herencia y polimorfismo o recursividad; tampoco hay que pasarse. Aunque si piensas que sólo vas a poder desarrollar estúpidas animaciones infantiles, te recomiendo que recorras la galería de proyectos destacados de la web de Scratch y visualices joyas como Sonic Advance 2, Piano~, 3D duplivert wave o Tarati.
Scratch es la mejor opción para comenzar desde cero (from scratch, en inglés) y obtener una sólida base que permita posteriormente migrar a entornos de desarrollo más “serios”.






