martes, 8 de diciembre de 2009

Desencriptar una cadena en Java

En prácticamente todas las aplicaciones, siempre es necesaria la encriptación de algún tipo de información. El ejemplo más simple son las contraseñas de usuario, información personal o cualquier tipo de información sensible dentro del ámbito de la aplicación.

Anteriormente, habíamos visto un mecanismo para encriptar contraseñas y convertir el texto encriptado en una cadena almacenable en una base de datos o fichero sin problemas de codificación, mediante el API estandar de Java.

Veamos ahora cómo sería el proceso inverso:

  String cadena = "WZMLNsMJeI2PDCPuWudVucLfRyQlffqA" +
                  "1yYKWLOLuCv2SzIcw0Aegh6w3o6FjQ3T";
  String semilla = "0123456789";
  String cadenaDesencriptada = null;
  String tmp = new String( ( semilla.trim().concat("99999999") ).substring(0, 8 ) );
      
  byte[] claveDesc = new BASE64Decoder().decodeBuffer( cadena );
  SecretKeySpec desKey = new SecretKeySpec( tmp.getBytes(), "DES");
      
  Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
  cipher.init(Cipher.DECRYPT_MODE, desKey);
      
  cadenaDesencriptada = new String(cipher.doFinal(claveDesc));


Tras ejecutar el anterior código, obtendríamos la cadena original "No se a quien odio más, a Batman o a Guti" dentro de la variable cadenaDesencriptada.

Evidentemente, todo el código del ejemplo habrá que incluirlo dentro del correspondiente bloque try-catch y realizar la gestión de excepciones adecuada según nuestra aplicación.

Ver artículo: Encriptar una cadena en Java

miércoles, 2 de diciembre de 2009

Manifiesto “En defensa de los derechos fundamentales en internet”

Compas


Ante la inclusión en el Anteproyecto de Ley de Economía sostenible de modificaciones legislativas que afectan al libre ejercicio de las libertades de expresión, información y el derecho de acceso a la cultura a través de Internet, los periodistas, bloggers, usuarios, profesionales y creadores de internet manifestamos nuestra firme oposición al proyecto, y declaramos que…


1.- Los derechos de autor no pueden situarse por encima de los derechos fundamentales de los ciudadanos, como el derecho a la privacidad, a la seguridad, a la presunción de inocencia, a la tutela judicial efectiva y a la libertad de expresión.

2.- La suspensión de derechos fundamentales es y debe seguir siendo competencia exclusiva del poder judicial. Ni un cierre sin sentencia. Este anteproyecto, en contra de lo establecido en el artículo 20.5 de la Constitución, pone en manos de un órgano no judicial -un organismo dependiente del ministerio de Cultura-, la potestad de impedir a los ciudadanos españoles el acceso a cualquier página web.

3.- La nueva legislación creará inseguridad jurídica en todo el sector tecnológico español, perjudicando uno de los pocos campos de desarrollo y futuro de nuestra economía, entorpeciendo la creación de empresas, introduciendo trabas a la libre competencia y ralentizando su proyección internacional.

4.- La nueva legislación propuesta amenaza a los nuevos creadores y entorpece la creación cultural. Con Internet y los sucesivos avances tecnológicos se ha democratizado extraordinariamente la creación y emisión de contenidos de todo tipo, que ya no provienen prevalentemente de las industrias culturales tradicionales, sino de multitud de fuentes diferentes.

5.- Los autores, como todos los trabajadores, tienen derecho a vivir de su trabajo con nuevas ideas creativas, modelos de negocio y actividades asociadas a sus creaciones. Intentar sostener con cambios legislativos a una industria obsoleta que no sabe adaptarse a este nuevo entorno no es ni justo ni realista. Si su modelo de negocio se basaba en el control de las copias de las obras y en Internet no es posible sin vulnerar derechos fundamentales, deberían buscar otro modelo.

6.- Consideramos que las industrias culturales necesitan para sobrevivir alternativas modernas, eficaces, creíbles y asequibles y que se adecuen a los nuevos usos sociales, en lugar de limitaciones tan desproporcionadas como ineficaces para el fin que dicen perseguir.

7.- Internet debe funcionar de forma libre y sin interferencias políticas auspiciadas por sectores que pretenden perpetuar obsoletos modelos de negocio e imposibilitar que el saber humano siga siendo libre.

8.- Exigimos que el Gobierno garantice por ley la neutralidad de la Red en España, ante cualquier presión que pueda producirse, como marco para el desarrollo de una economía sostenible y realista de cara al futuro.

9.- Proponemos una verdadera reforma del derecho de propiedad intelectual orientada a su fin: devolver a la sociedad el conocimiento, promover el dominio público y limitar los abusos de las entidades gestoras.

10.- En democracia las leyes y sus modificaciones deben aprobarse tras el oportuno debate público y habiendo consultado previamente a todas las partes implicadas. No es de recibo que se realicen cambios legislativos que afectan a derechos fundamentales en una ley no orgánica y que versa sobre otra materia.

domingo, 22 de noviembre de 2009

Encriptar una cadena en Java

En prácticamente todas las aplicaciones, siempre es necesaria la encriptación de algún tipo de información. El ejemplo más simple son las contraseñas de usuario, información personal o cualquier tipo de información sensible dentro del ámbito de la aplicación.

Veamos cómo podemos codificar una cadena cualquiera utilizando el API estandar de Java.

        String claveEncriptada = null;
        String claveOriginal = "No se a quien odio más, a Batman o a Guti";
        String semilla = "0123456789";

        // Generamos una clave secreta.
        SecretKeySpec desKey = new SecretKeySpec(new String((semilla.trim().concat("99999999")).substring(0, 8)).getBytes(), "DES");
        Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, desKey);
        byte[] claveEncriptadaBytes = cipher.doFinal( claveOriginal.getBytes() );
        claveEncriptada = new BASE64Encoder().encode( claveEncriptadaBytes );






Evidentemente el código mostrado anteriormente habrá que incluirlo en un método con su generador de clave y su bloque try-catch.

Como podemos ver, la cadena que tratamos de codificar es: "No se a quien odio más, a Batman o a Guti" y el resultado que obtendríamos si ejecutaramos las instrucciones del listado sería: "WZMLNsMJeI2PDCPuWudVucLfRyQlffqA1yYKWLOLuCv2SzIcw0Aegh6w3o6FjQ3T".

La semilla, es utilizada por el algoritmo de encriptación para cifrar la cadena. Si quisieramos desencriptar la cadena obtenida, necesitaríamos la semilla para poder hacerlo. Es como la llave que abre la caja fuerte que contiene el contenido desencriptado original. A la hora de realizar una aplicación es de suma importancia que cada dato que encriptemos tenga una semilla diferente para no comprometer el total de la información en el caso de que la misma sea descubierta. El mecanismo para la elección debe ser elegido cuidadosamente para dificultar el trabajo a un posible "ladrón" que quisiera acceder a la información.

Es importante tener en cuenta que la encriptación genera una cadena de bytes, los cuales, transformados en una cadena de carácteres podría implicar la existencia de carácteres extraños en la misma, cosa que nos podría dar problemas a la hora de almacenar la información encriptada en una base de datos si no tenemos en cuenta que podemos insertar dicho tipo de cadenas a la hora de almacenarlas en fichero o base de datos. Para evitar dicho problema, utilizamos el codificación BASE64.

Ver artículo: Desencriptar una cadena en Java

Gracias a Gomstor por encontrar un error en el código que ya ha sido corregido.

sábado, 14 de noviembre de 2009

DNI, NIF, NIE

Muchas veces, a la hora de escribir un programa, hacer una web, etc, nos vemos en la necesidad de recoger información personal de un usuario, y en algunos casos, entre dicha información nos encontramos con el NIF/NIE de alguna persona.

Siempre que me he puesto a buscar por internet adelante, he encontrado montones de scripts que validan, calculan y formatean los NIFs, pero nunca he encontrado uno que me sirviera para los números de identificación de extranjeros, NIE.

¿Qué es eso del NIE? Pues muy sencillo, es un NIF para extranjeros. En un principio puede parecer una chorrada, pero no lo es en absoluto. Por ejemplo: Un inglés, llamémosle Paul Gascoigne, por ejemplo, quiere comprarse un pisito en Benidorm para pasar sus vacaciones en alguna terraza de la ciudad nadando en cerveza. Para realizar la compra necesitará un número de identificación ante hacienda (que somos todos, incuidos algunos extranjeros). Un NIF no se le puede dar, pues es sólo para personas con nacionalidad española. Por eso David, deberá obtener un NIE antes de poder adquirir su pisito-resaquero.

Básicamente un NIE es lo mismo que un NIF pero en el que se ha cambiado su primer dígito por una letra, que puede ser X, Y o Z. Por otro lado, a la hora de calcular la letra final, estas X,Y o Z se substituyen por un 0, 1 o 2 respectivamente, a partir de este momento, el cálculo es exáctamente el mismo que para el NIF.

A continuación muesto una serie de funciones javascript para validar y calcular automáticamente tanto NIF como NIE:

/*
  * Por CNG (www.trapallada.com).
  */
  function esNumerico(x)
  {
    var expresionRegularNDigitos = /^(\d*)$/;
    return x.match(expresionRegularNDigitos);
  }

  function esNifNie(x)
  {
    var expresionRegularNIE = /^[X-Z0-9]{1}[0-9]{7}$/;
    return x.match(expresionRegularNIE);
  }

  function obtenLetraNIF ( dni, destino )
  {
    dni.value = dni.value.toUpperCase();
    if ( esNifNie( dni.value ) )
    {
      var nifTmp = '';
      if ( esNumerico( dni.value ) )
      {
        nifTmp = dni.value;
      }
      else
      {
        switch( dni.value.charAt(0).toUpperCase() )
        {
          case 'X': nifTmp = dni.value.replace(/X/gi, "0");
                    break;
          case 'Y': nifTmp = dni.value.replace(/Y/gi, "1");
                    break;
          case 'Z': nifTmp = dni.value.replace(/Z/gi, "2");
                    break;
          default:  alert('NIF/NIE incorrecto');
        }
      }

        if ( nifTmp.length == 8 )
        {
          var cadena = 'TRWAGMYFPDXBNJZSQVHLCKET';
          var posicion = nifTmp % 23;
          destino.value = cadena.charAt(posicion);
        }
        else
        {
          destino.value = '';
        }
      }
      else
      {
        alert('NIF/NIE incorrecto');
      }
    }  
  }


Para probar este código deberemos incluir un inputbox html que realice las llamadas adecuadas:







CC-GNU LGPL


Este software está sujeto a la CC-GNU LGPL o superior.

domingo, 8 de noviembre de 2009

Convertir código ASP a PHP.

Problema: Dispongo de una web que hice hace tiempo utilizando tecnología ASP con conexiones a una base de datos access y ahora:

1- Quiero cambiar de tipo de servidor en mi proveedor de hospedaje a uno en linux para pagar menos al mes.

2- Quiero dejar de utilizar mi web para utilizar alguna herramienta de publicación como Wordpress o un CMS.

En ambos casos me gustaría poder seguir utilizando algunas de mis funciones ASP sin tener que recodificar todo manualmente, ya que eso me haría perder bastante tiempo.

Solución: ¡¡¡asp2php!!!

Se trata de un programita que te permite convertir código asp a php, respetando bastante la estructura original de los fichero, por lo que te será fácil retocar el código php generado si no tienes demasiados conocimientos de php, aunque sea símplemente por comparación con el archivo ASP original.

Pero veamos un ejemplo con los resultados de la conversión:

' Por CNG (www.trapallada.com).
Function getLiteral(intIdLiteral)
Set DB = Server.CreateObject("ADODB.Connection")
Set RS = Server.CreateObject("ADODB.Recordset")
DB.Mode = adModeReadWrite
DB.Open "dsn=miDSN;"

strSQL = "select literal from tLiterales where id=" + CStr(intIdLiteral)
RS.Open strSQL, DB, 3, 2
If RS.EOF or RS.BOF Then
strLiteral= "null"
Else
strLiteral= Trim(RS.Fields(0).Value)
End If
RS.Close
DB.Close
getLiteral= strENUNCIADO
End Function

generaría

// Por CNG (www.trapallada.com).
function getLiteral($intIdLiteral)
{
extract($GLOBALS);

// $DB is of type "ADODB.Connection"
// $RS is of type "ADODB.Recordset"
echo $adModeReadWrite;
$DB=mysql_connect("servidorDDSS","","");
mysql_select_db("",$DB);

$strSQL="select literal from tLiterales where id="+($intIdLiteral);
$rs=mysql_query($strSQL);
if (($RS==0) || ($RS_BOF==1))
{
$strLiteral="null";
}
else
{
$strLiteral=trim((0)->$Value);
}
mysql_close($DB);
$function_ret=$strLiteral;
return $function_ret;
}


El programa funciona en línea de comandos, pero para evitar lo engorroso del mismo, existen diferentes frontales para windows, MacOX e incluso para entorno web.  Yo sólo he probado el asp2php shell, con resultados magníficos por cierto. Lo único que hay que hacer es descomprimir el los archivos de asp2php y de asp2php shell en la misma carpeta.

jueves, 16 de abril de 2009

Ashton Kutcher vs CNN Breaking News

twitter_128x128De vez en cuando, el tedio habitual en que Internet se ha convertido para mi últimamente, se ve roto por algún video chorra o alguna polémica internetera. El pasado martes, me vi en una de esas situaciones.

Resulta, que el pasado lunes 13, al amigo Ashton Kutches (aplusk) no se le ocurrió otra cosa que grabar y publicar en youtube un video en el que reta a  CNN Breaking News (cnnbrk) de una manera muy particular. Si alcanza un millón de seguidores en Twitter antes que la CNN irá a casa de Ted Turnes (propietario de CNN) a todar el timbre y salir corriendo.


Al día sieguiente un video con el presentador de CNN Breaking News, Larry King,  contestaba al actor diciendole que no tenía nada que hacer, que la CNN era muy grande y que perdería, y aprovechó para invitarlo al programa para entrevistarlo.




El reto de Kutcher, se ha convertido en lo más entretenido de Internet últimamente. En el momento del reto CNN iba bastante por delante de él, y ayer le sacaba unos 8.000 seguidores por la mañana, aunque a la noche había conseguido recortar la distancia a 4000. Durante la noche del jueves al viernes (horario europeo) Kutcher ha tomado la delantera, y el resultado en el momento de escribir este artículo es:


Ashton Kutcher 995.251 - CNN Breaking News 994.249


¿Qué pasará en la lucha de David contra Goliath, Goliath contra Goliath?

miércoles, 25 de marzo de 2009

Codificación de los acentos en páginas web

file-html-128Generalmente cuando uno prepara una página web estática se limita a escribir "a saco" el texto que esta debe mostrar, incluyendo acentos y carácteres especiales. Esto no supone un problema si utilizamos un editor de páginas web que automáticamente fije la codificación del contenido, aunque lo lógico sería utilizar los tags de HTML para su correcta visualización. Por ejemplo, se deberá usar á (a aguda) para mostrar una á.

El problema se puede presentar al crear una página web dinámicamente, ya sea con ASP, jsp, php o cualquier otra tecnología en la que los textos que se deben mostrar se obtienen de una fuente de datos como una tabla de una base de datos y que han sido introducidos por terceros. En algunos casos, como sobre todo sucede con el navegador Firefox nos podemos encontrar con sorpresas, como ver unos rombitos en el lugar de alguna vocal acentuada. Ver un ejemplo (sólo firefox).

Para evitar este problema, deberemos incluir en la cabecera de la página el siguiente meta tag:

<meta content="text/html; charset=iso-8859-1" http-equiv="Content-Type"></meta>

Lo que informa al navegador de la codificación que debe utilizar para interpretar los carácteres de la página mostrada.

Otra opción es obligar al servidor a incluir dicho tag automáticamente. Esto se hace añadiendo al archivo .htaccess lo siguiente:

AddType text/html;charset=ISO-8859-1 .html

miércoles, 18 de marzo de 2009

Parámetros en línea de comandos en java

Una de las cosas más engorrosas a la hora de preparar una pequeña aplicación java en línea de comandos,al igual que en otros lenguajes de programación, es el tener que controlar todos los parámetros que se le pasan a la aplicación, el orden de los mismos, que vayan separados al estilo -s -l -r o -slr...

Existe un proyecto de Martian Software Inc. llamado JSAP, que será de gran ayuda para este tipo de cosas. Lo descubrí casi de casualidad y me parece una maravilla. Pero veamos un ejemplo: Imaginemos un programa que lee de un archivo una serie de datos, los procesa, y los escribe en un archivo de salida, exceptuando los datos que generan alguna incidencia que son grabados en un tercer archivo de errores, la aplicación además parará cuando se produzcan un número de errores igual al indicado en otro parámetro, es decir el clásico problema de metodología Warnier.

El programa debería ejecutarse con un comando del estilo de:

java com.trapallada.programa -i entrada.txt -o salida.txt -e errores.txt -n 500


donde los parámetros podrían ser aparecer en cualquier orden.

/*
* Por CNG (www.trapallada.com).
*/
public static void main(String[] args)
{
try
{
JSAP jsap = new JSAP();

// Se crean los diferentes parámetros:
// Parámetro del fichero de entrada
FlaggedOption optEntrada = new FlaggedOption("Fichero de Entrada")
.setStringParser(JSAP.STRING_PARSER)
.setRequired(true)
.setShortFlag('i')
.setLongFlag("input");

// Parámetro del fichero de salida
FlaggedOption optSalida = new FlaggedOption("Fichero de Salida")
.setStringParser(JSAP.STRING_PARSER)
.setRequired(true)
.setShortFlag('o')
.setLongFlag("output");

// Parámetro del fichero de errores
FlaggedOption optErrores = new FlaggedOption("Fichero de Errores")
.setStringParser(JSAP.STRING_PARSER)
.setRequired(true)
.setShortFlag('e')
.setLongFlag("errores");

// Parámetro del fichero de número de errores (no obligatorio)
FlaggedOption optNumeroErrores = new FlaggedOption("Número de Errores")
.setStringParser(JSAP.INTEGER_PARSER)
.setRequired(false)
.setShortFlag('n')
.setLongFlag("numErrores");

// Registramos los parámetros
jsap.registerParameter(optEntrada);
jsap.registerParameter(optSalida);
jsap.registerParameter(optErrores);
jsap.registerParameter(optNumeroErrores);

// Se procesan los argumentos de la línea de comandos
JSAPResult config = jsap.parse(args);

// Si se produce algún error generamos el mensaje de error con JSAP.
if (!config.success())
{
System.err.println();
System.err.println("Uso: java " + Lector.class.getName());
System.err.println(" " + jsap.getUsage());
System.err.println();
System.exit(1);
}

// Se recogen los datos del la configuración cargada desde los
// parámetros de la línea de comandos.
String entrada = config.getString(optEntrada.getID());
String salida = config.getString(optSalida.getID());
String errores = config.getString(optErrores.getID());
Integer numErrores = new Integer(config.getInt(optNumeroErrores.getID()));
}
catch (Exception e)
{
e.printStackTrace();
}
}

Esto sería lo que devolvería la ejecución de la clase en el caso de no poner nada a continuación de la llamada a la misma (sin parámetros).

Uso: java com.trapallada.programa
(-i|--input) <Fichero de Entrada> (-o|--output) <Fichero de Salida> (-e|--errores) <Fichero de Errores> [(-n|--numErrores) <Número de Errores>]

miércoles, 4 de marzo de 2009

Menos da una piedra

ppEso es lo que debe estar pensando "nuestro amiguito Marianico el Corto", y no, no me refiero al lamentable personaje de los programas de televisión tipo José Luis Moreno.

La verdad es que desde 2004 y el Rubalcabazo, es la primera vez que los Populares pueden presumir de haber ganado algo de verdad. Pero, si se ojean un poco los datos, sin necesidad de profundizar gran cosa podemos ver un par de datos que son como para que los dirigentes del PP se preocupen un poco, y claro, RuizGa, el superhéroe de las páginas interiores de El Pais se frote las manos y se dedique a preparar sus zapatos de la primera comunión para ponerselos al minuto de que se lleven los restos de "Marianico y sus peones".

En Galicia el PP ha sacado mayoría absoluta, pero en votos sólo ha subido 4000 (aún falta el voto de la inmigración), pero en el Pais Vasco, ha bajado la friolera de 65.000, lo que supone un neto de una pérdida de 61.000. ¿Es realmente esto como para sacar pecho? Sobre todo, teniendo en cuenta dos cosas: En Galicia, son muchos los que han apelado al voto útil para echar e los nacionalistas (esa corriente política que convierte en mierda todo lo que toca), y en el Pais Vasco, había 8 escaños más a repartir entre todos, y aún así, han perdido 2.

¿Qué pasará en las europeas cuando a la gente le importe "un huevo" su voto y decida castigar los bandazos de Marianico y demás con un voto de castigo a UPyD o la abstención? Lo veremos en junio.

lunes, 23 de febrero de 2009

Batman, el superheroe más cutre de entre los "Clásicos"

Batman me cae mal, siempre me ha caido mal, es algo irracional, es como lo de Peter Pan, no lo soporto, pero si bien Peter Pan me cae mal porque es un pijo chungo, Batman me cae mal símplemente por ser un quiero y no puedo, entre otras cosas en las que no entraré.

Realmente Batman no tiene poder alguno, es todo a base de cachibaches y artilugios con ganchos, cables y demás ferralla. No es como Superman que te puede congelar con su super-aliento o hacerte una radiografía sólo com mirarte. Si tienes un RPG y pillas a Batman un poquillo despistado, te lo cargas sin problemas, y si no lo pillas despistado, siempre puedes poner 4 o 5 RPGs y será carne de cañón.

Spiderman puede envolverte con sus telas de araña, subirse por las paredes, tiene un oido privilegiado, pero ¿Batman? Como no se ponga un Whisper XL amplificado va de culo. Robin podría llamar a Corrupción de Menores estando en la misma sala que él y Batman no se enteraría.

¿Qué te puede hacer Batman realmente? ¿Darte de hostias? ¿tirarte cosas?, ¿insultarte?, vale, él está entrenado y yo no ¿y qué? Se soluciona con los 4 o 5 RPG. Intenta cargarte a Superman con un lanzacohetes, le puede dar la risa. Y luego evidentemente preparate que vas a ir para casa con el culo calentito. Y hablando de culos: ¿Es mayor de edad Robin?

Además, no ireis a comparar a los enemigos de Batman con los de Superman por no ir más lejos. El Joker no deja de ser un pirado, una especie de Emilio Aragón traumatizado por la cancelación de los Payasos de la Tele. ¿El Pinguino? Le pones la mno en la frente y no es capaz de tocarte, y así todos. Si Lex Luthor se metiera con Batman sí que iba a "cagar masilla".

Y ahora una selección de los mejores Batman de la red:



Y el grandioso y único disfráz de Batman, el que realmente nos dice: "Tú podrías ser Batman" es:

jueves, 19 de febrero de 2009

Evitar inicialización accidental de Informix

En mi opinión, una de las cosas que los señores de IBM debería corregir, cuando publiquen el esperado Infomix Cheetah, es el tema de la opción de inicialiación de las bases de datos con la opción -i del comando oninit.

Es relativamente fácil lanzar el comando oninit –i accidentalmente y perder las bases de datos, por lo que es recomendable enmascarar el programa oninit. Para esto renombraremos el comando oninit de $INFORMIXDIR/bin/oninit a $INFORMIXDIR/bin/oninit.cmd.

Luego creamos un script oninit que filtre el uso de la opción –i

# oninit
# Por CNG (www.trapallada.com).
#
# Script que enmascara el oninit de informix para
# evitar el oninit -i que inicializa la base de datos

ARGUMENTOS=""
LANZAR=1

while getopts ivyI opcion
do
case $opcion in
i) echo -e "\n   La opcion -i esta bloqueada para evitar inicializaciones"
echo "   accidentales de la base de datos. Utilice la opcion -I"
echo -e "   i mayuscula para inicializar la base de datos.\n"
LANZAR=0;;
v) ARGUMENTOS=v${ARGUMENTOS};;
y) ARGUMENTOS=y${ARGUMENTOS};;
I) ARGUMENTOS=i${ARGUMENTOS};;
esac
done

if ( test $LANZAR -eq 1 ) then
oninit.cmd -${ARGUMENTOS}
fi

Ordenar mis fotos por carpetas

Siempre he tenido un serio problema a la hora de organizar las fotografías en mi disco duro. Al principio volcaba todo en una misma carpeta, cosa que en cuestión de pocas descargas de la cámara, convertía la carpeta en algo totalmente invisitable. El segundo paso fue el crear carpetas con nombres descriptivos y guardar en ellas las fotografías, pero aún así la cosa era un infierno.

Las aplicaciones como Picasa, ACD See, PhotoMesa permiten gestionar bastante bien las fotografías, pero a mi, como buen usuario proviniente del MS-DOS al que le gusta saber dónde están las cosas en mi disco duro, y no perder el control sobre él, no acababan de convencerme.

Tras una breve incursión en el mundo del Linux, descubrí la aplicación f-Spot, que realizaba una clasificación en carpetas de las fotografías en función de los datos Exif de los archivos JPG.

Ya de vuelta al mundo Windows, y tras decantarme por Picasa, principalmente por su facilidad de uso (no para mi, sino para mi mujer), me encontré con mi eterno problema de clasificar las fotografías. Por lo que en ese momento me decidí a crear mi propio programita Java que clasifique en carpetas las fotografías a partir de sus datos Exif.

Lo primero de todo es obtener las fotografías de origen a partir de una ruta:

/*
* Por CNG (www.trapallada.com).
*/

/**
* Devuelve una colección con todos los ficheros JPG de una carpeta.
* Para obtener esa colección recorre recursivamente todo el árbol de
* directorios bajo la carpeta indicada.
* @param f File indicando la carpeta en la que realizar la búsqueda recursiva.
* @return Una Colección con todos los ficheros baja la carpeta pasada al método.
*/
private static Collection getFiles( File f ) {
Collection c = new ArrayList();
if ( f.isDirectory() ) {
File[] listOfFiles = f.listFiles();
for (int i = 0; i < listOfFiles.length; i++) {
c.addAll( getFiles( listOfFiles[i]) );
}
} else {
JFileChooser chooser = new JFileChooser();
if ( chooser.getTypeDescription(f).equals("Archivo JPG") ) c.add(f);
}
return c;
}

A partir de la colección de ficheros JPG, y mediante la librería metadata-extractor, yo he usado la versión 2.3.1, podemos generar un nuevo nombre de fichero y mover el archivo original de la colección obtenida a su destino definitivo.

// Por CNG (www.trapallada.com).
try {
String salida = "D:/Mis documentos/Mis imágenes/preImportado";
String entrada = "D:/CarpetaOrigen";

Collection files = getFiles( new File(entrada) );

Iterator itFiles = files.iterator();
while ( itFiles.hasNext() ) {
File ficheroJpg = (File) itFiles.next();
try {
Metadata metadata = JpegMetadataReader.readMetadata( ficheroJpg );
Directory exif = metadata.getDirectory( Class.forName("com.drew.metadata.exif.ExifDirectory") );

Calendar fecha = Calendar.getInstance();
try {
fecha.setTime( exif.getDate( ExifDirectory.TAG_DATETIME_ORIGINAL ) );
File toFile = new File( salida + "/" + fecha.get( Calendar.YEAR ) + "-" +
Formateador.fill( new Integer( fecha.get( Calendar.MONTH ) + 1 ).toString(),
'0', 2, Formateador.IZQUIERDA ) + "/" +
ficheroJpg.getName() );
Ficheros.moveFile( ficheroJpg, toFile);
}
catch ( MetadataException j ) {
System.out.println("ERROR: " + ficheroJpg.getName() );
}
} catch ( JpegProcessingException e ) {
e.printStackTrace();
}
}
}
catch ( Exception e )
{
e.printStackTrace();
}
}

Nota: El método Formateador.fill tiene el siguiente javadoc:
/**
* M&amp;amp;amp;amp;eacute;todo que devuelve la cadena rellena con el caracter "caracterRelleno", hasta
* ocupar "longitud" posiciones, desde el lado indicado.
*
* @param cadena: Cadena a ser formateada
* @param caracterRelleno: Caracter con el que se va a rellenar
* @param longitud: Indica la longitud de la cadena resultante
* @param lado: nos indica en que lado situar los caracteres de Relleno
* @return Cadena rellena
*/
Nota 2: No creo que haga falta explicar lo que hace el método Ficheros.moveFile.

miércoles, 18 de febrero de 2009

Cargador de móvil universal... ¡Por fin!

En un cajón de mi casa, almaceno un montón de cables de cargadores, ¿y por qué los almaceno? Pues no lo se. La verdad es que en contadas ocasiones he podido reutilizar un cargador de móviles. Que si los extraños conectores de Ericsson, los de patilla gorda de Nokia, los planos de Siemens, los de Motorola, similares a los de Nokia pero incompatibles, los de patilla fina de Nokia... y así hasta el infinito.

Pero por suerte, para todos los que sufren el mismo problema que sufro yo, parece que al podremos ver la luz al final de túnel. Al parecer una asociación de diferentes fabricantes de teléfonos móviles, ha decidido implantar un único modelo de conector de carga para todos sus productos. El conector elegido es el Micro-USB, aunque el artículo de la GSM Association no especifica si será el Micro-USB AB o el Micro-USB B. En cualquier caso la noticia es buena, ya que GSMA engloba el 84% del mercado de las comunicaciones móviles.

Curiosamente, una de las "estrellas" de los últimos tiempos en el mundo de la telefonía móvil el iPhone de Apple, en principio queda fuera de este acuerdo, y es que al parecer no tienen intención ninguna de unirse al grupo de empresas que implantarán el conector único. Otra razón más para incrementar la tiña que le tengo a empresa de la manzanita.

En cualquier caso la noticila la teneis en el portal de GSMA.

jueves, 12 de febrero de 2009

Obtener los campos SERIAL de Informix tras un INSERT



Problema:

Tras hacer un INSERT en una tabla de Informix que contiene campos del tipo SERIAL nos encontramos con que tras realizarlo, tenemos todos los datos del registro excepto los autogenerados por la base de dato.

Solución:

// Por CNG (www.trapallada.com).
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;

String queryString = "INSERT INTO " + TABLA + " (" + CAMPOS +
") VALUES ( ?,?,?,? )";
preparedStatement = conn.prepareStatement(queryString,
Statement.RETURN_GENERATED_KEYS);

int i = 1;
// El primer campo de la tabla es SERIAL
preparedStatement.setInt(i++, 0);
preparedStatement.setString( i++, vo.getCampo2() );
preparedStatement.setString(i++, vo.getCampo3() );
preparedStatement.setString(i++, vo.getCampo4() );

int insertedRows = preparedStatement.executeUpdate();
resultSet = preparedStatement.getGeneratedKeys();

resultSet.next();
vo.setCampo1( resultSet.getInt(1) );

En el momento de crear el PreparedStatement incluimos el parámetro Statement.RETURN_GENERATED_KEYS para indicarle a la aplicación que recupere los valores de los SERIAL generados por la base de datos.

Tras ejecutar el INSERT, se recupera un ResultSet con los campos SERIAL generados con el método getGeneratedKeys() del PreparedStatement.

Tras eso, accedemos al ResultSet para obtener los valores.

martes, 10 de febrero de 2009

Necesito un Traductor

Es es lo primero que he pensado ayer al hablar un rato con mi hija mayor, que va a cumplir dos años el próximo lunes.

La verdad es que me está bien, por preguntarle qué quería de regalo de cumple, cosa a la que ella contestó:

sanitos, ajules, coluto ajul y lalito



Bueno, realmente primero dijo sanitos, luego, tirandole un poco más de la lengua añadió ajules y así sucesivamente.

Actualizazación: La verdad es que no hay nada como dormir un poco para que se te acalaren las ideas. Ya he sido capaz de entender el mensaje:

  • Sanitos: Gusanitos

  • Ajules: Plastelina

  • Coluto ajul: Columpio azul

  • Lalito: Regalito


En cualquier caso ya tengo lista con la que "currarme" el regalo de cumple.

viernes, 6 de febrero de 2009

Historias incompletas



La verdad es que uno, a la hora ve ver los informativos en la tele, oir las noticias en la radio o leerlas en la prensa, en la mayoría de los casos no es capaz de imaginarse la magnitud de aquello que está viendo u oyendo. Todo esto, además, se ha acentuado en los últimos años por la efimeridad de las noticias, llegando al punto de que una cosa que es noticia a las nueve de la mañana, deja de serlo antes de la hora de comer.

Hoy me he visto involucrado indirectamente en una de esas que uno no es capaz de entender en su totalidad, ni de adivinar el alcance de todo lo que implica. Relataré lo que me ha sucedido:

A media tarde me llamó un amigo para acudir a la inaguración de un restaurante cerca de casa, y mientras preparaba a las dos niñas, para que la abuela sólo tuviera que acostarlas, me sonó el teléfono, al coger el mismo, me fijé que el número llamante era un número oculto, cosa a la que no di importancia y respondí. Al otro lado de la comunicación una voz se me identificó como de la Policía, y me preguntó el cómo llegar hasta mi domicilio, ya que se tenían que pasar por él, dos agentes de la Policía Judicial. El corazón me dió un brinco, cosa que mi interlocutor notó y se apresuró a tranquilizarme: Me explicó que recientemente en Málaga había aparecido un bebé abandonado, y que a partir de la única pista que tenían, que era la pinza del cordón umbilical, y a través de los datos del fabricante de la misma, estaban realizando un control exhaustivo de todos los bebés nacidos durante el pasado mes de diciembre, con el fin de encontrar a la persona que abandonó a la criatura.

Pasada media hora, dos agentes de la Policía Judicial se personaron en casa para realizar la comprobación, no sin antes volvernos a explicar el motivo de su visita, con algún detalle más, como puede ser que el control que están llevando a cabo lo hacen a nivel de toda España. El Policía se asomó al moisés donde dormía Reyes y nos informó de que ya estaba todo listo.

Pero volvamos a la noticia en sí: "Aparece en Málaga un bebé de 6 semanas abandonado" (por ejemplo). ¿Qué cantidad de cosas hay detrás de esa noticia? Una madre asustada y/o desalmada que abandona a su hijo, una persona que lo encuentra, todas las personas de los servicios sociales que se ocupan de la criatura, policías, pediatras, jueces, investigadores, padres investigados, persona de centros sanitarios "interrogados"... Una simple noticia de una columna en una página impar implica el despliegue y la interacción de decenas de personas... Imaginemos ahora una noticia de portada.

miércoles, 4 de febrero de 2009

Cuando ser pistolero molaba



No me parece bién que a los miembros de ETA le llamen pistoleros, de hecho estoy harto de que en la prensa se utilice este término para hablar de simples asesinos.

Ser un pistolero es muy guay. Yo quería haber sido pistolero, quería ponerme un sombrero como el de Clint Eastwood y un cinturón con dos pistolas, montar a caballo con mi pañuelo rojo al cuello, dirigiendo el ganado por las estensas planicies de Texas. Dormir sobre el suelo con mi cabeza sobre la silla de montar, enfrentarme con mis pistolas a los cuatreros, forajidos y alguna vez los indios.

Pero ¿un llamar a etarra pistolero? Pues no, un etarra es un asesino, una sabandija, con perdones para estos  entrañables animalitos, la ez de la sociedad.

Pistoleros que lo sean los chavales, montados a lomos de las escobas de sus padres y con un palo torcido en la mano a modo de pistola.

lunes, 2 de febrero de 2009

Los Goya



Un año más la "industria" "cinematográfica" española se ha mirado el ombligo y ha repartido premios a imágen y semejanza de los "satánicos" Oscar de Hollywood, de quienes, aunque sea por oposición beben (véase la alfombra verde).

Acabo de leer en algún periodico la respuesta del público: Sr. y Sra. Smith, líder de audiencia.

Tras las constantes referencias en la "gala" a las descargas P2P, me gustaría saber qué porcentaje de las descargas de películas que se producen en España son debidas a películas españolas, y qué porcentaje son de pelícuas extranjeras.

Es como para recapacitar ¿no?

A mi personalmente, del cine español, rescataría cinco o seis películas. El resto, son francamente prescindibles, pero claro, hay que seguir financiando la "cultura" de los estómagos agradecidos amigetes de la progresía gobernante. ¡¡¡Es espectáculo debe continuar!!! ¡¡¡Más madera!!!

sábado, 17 de enero de 2009

Entrevista a un blogger



1. ¿Por qué creaste o ingresaste en tu blog? Por que quería ver de qué iba el rollo ese de los blogs. Pro probar, como más o menos todo a lo que me he apuntado en Internet.

2. ¿Cuántas bitácoras lees al día a parte de la tuya? Leo dos o tres, pero ojeo lo artículos de muchas, además, luego siempre pululo un rato por la red a ver que encuentro.

3. ¿Sabes lo que es un lector de rss? Si, y de hecho los uso porque son cómodos para seguir varios blogs, pero no me gustan demasiado. Para los periodicos por ejemplo, los odio.

4. ¿Has baneado alguna vez a gente de los comentarios? Sí, y es que hay gente que es realmente maleducada. Quisiera que los comentarios ofensivos fueran causados por mis maravillosos argumentos, pero más bien, creo que es porque la gente no suele ser capaz de expresar las pocas ideas que tiene de manera escrita, con órden y educación. De hecho yo muchas veces sufro del mismo problema.

5. ¿Cuál es el beneficio y cuál el perjuicio que te ocasiona este mundo de los blogs? Beneficio: Me entretengo y trato de conservar e incluso mejorar mi prosa escrita. Perjuicio: Más trabajo y sentimiento de culpabilidad cuando paso temporadas sin escribir ningún post y pienso que voy a perder los pocos lectores que pueda tener.

jueves, 15 de enero de 2009

Topónimos y Armas Políticas


Reconozco que este es un tema que me cabrea en particular. Sobretodo por la cantidad de argumentos chorras y subnormalidades que se dicen.


En mi caso, al hablar de la capital del Segre, me sale Lérida y otras Lleida, al igual que me pasa con otras ciudades, como Orense, La Coruña o Gerona. Más de una vez se ha llamado mi atención por no utilizar la forma oficial del nombre, a lo que yo siempre suelo contestar con la típica, y por otro lado de sentido común, argumentación de que si estoy hablando en castellano, digo el nombre en castellano. De la misma manera que no digo “Me voy de fin de semana a London”, entre otras cosas porque sería posible que algún amigo me dijera “Mira que eres gilipollas cuando quieres”, tampoco diría “Los mejores aceites de oliva son los de Lleida” por las mismas razones.


Santiago de Compostela es el nombre de una hermosa ciudad del noroeste de España, tanto en gallego como en castellano. Su nombre oficial está regulado por leyes. La Xunta de Galicia dispone de un nomenclátor con todos los nombres oficiales de ayuntamientos, parroquias y lugares de Galicia. ¿Por qué entonces yo me veo obligado a tener que decir Lleida cuando hablo en castellano y en los libros de texto en catalán se sigue hablando del “Camí de Sant Jaume”, o en la información del tiempo en TV3 hablan de "Terol" en lugar de Teruel?



Se utilizan los idiomas, los nombres de los lugares, los sentimientos patrióticos de la gente como armas políticas, especialmente por parte de los que necesitan dar sentido a su existencia. Pero esto no es malo del todo, siempre ha habido trileros, estafadores y timadores, lo que es malo es que la gente a pesar de verlo, prefiere mirar para otro lado, generalmente a la tele.

miércoles, 14 de enero de 2009

De victoria en victoria hasta la derrota final



No, este post inicial de la nueva temporada no está dedicado a Izquierda Unida. Pretendo que este artículo sea una pequeña reflexión que me han provocado dos o tres lecturas recientes y alguna peli, y la conclusión es que sí, los occidentales nos estamos volviendo gilipollas integrales.

¿Qué está pasando? ¿Tan cubiertas tenemos nuestras necesidades básicas que podemos dedicarnos a hacer el gilipollas integral? Se ponen de moda cosas tan chorras como los platos de Ferrán Adriá o las cartas de aguas en los restaurante, aparecen memeces como el Proyecto Gran Simio o el Frente de Liberación de los Enanos de Jardín. Eso sí, renegamos de todo lo que ha creado nuestra forma de vida, renegamos del conocimiento, la filosofía cristiano-romana, de nuestra identidad cultural, cambiandolo todo por una cultura del dinero.

El otro día estuve viendo la película "Enemigo a las Puertas", y se me ocurrió el escribir este artículo. La generación actual, no sabe lo que ha sido luchar y ganarse lo que tiene, evidentemente yo tampoco lo se, pues nací en 1974, pero me pregunto: ¿Cuanta gente ha entregado su vida en una lucha para conseguir todo aquello que ahora disfrutamos sin habernoslo ganado? ¿Cuantos de los jóvenes de ahora estarían dispuestos a jugarse todo lo que tienen y son? Seguramente ninguno, preferirán seguir jugando a la Play, mandando SMSs y comprando CDs en el Top Manta.

No tenemos arreglo y eso es un drama, pero el verdadero drama para nosotros es que los enemigos de Occidente, osea los nuestros, no se parecen en nada a nosotros, ellos están todo el tiempo preparados para tratar de imponernos su modo de vida, sus costumbres, su credo. Porque sí, el Islam es el enemigo de occidente.

Por un lado, todo eso de la multiculturalidad y la Alianza de Civilizaciones no son más que patochadas propias de una izquierda huerfana de ideología tras el fracaso del comunismo, que necesita algo a lo que agarrarse para justificar su propia existencia.

Por otro lado, las medidas a lo bestia de los EE.UU. no hacen más que agravar la situación, el enfrentamiento entre dos culturas, ya de por si tan diferentes, que están condenadas a enfrentarse, tal y como ha pasado innumerables veces a lo largo de la historia. Está claro que la estrategia no ha funcionado, y es complicado que cualquier gobierno occidental pueda conseguir derrotar al enemigo de Occidente, porque exigiría un plan de actuación de muchos años, mas que los cuatro que duran una legislatura en la mayor parte de los paises occidentales. Y claro, ya se sabe, que los gobernantes democráticos no tratan de gobernar para el pueblo, sino gobernar para ganar la reelección, cosa que es muy diferente.

La guerra ha empezado y a pesar de ganar las batallas, está perdia de antemano.