Jan 31

cafecito de java “cafe babe”

Una curiosidad que conocía desde hace tiempo, pero no sé por qué acabo de recordar.

Si cogemos un fichero .class generado por java y vemos sus bytes en hexadecimal, a ser posible en un procesador no intel, obtendremos la siguiente salida

$ od -x fichero.class
0000000 cafe babe 0000 002e 0053 0a00 1400 2e08
0000020 002f 0700 300a 0003 002e 0700 310a 0005
0000040 0032 0a00 0300 330a 0003 0034 0b00 3500

“od -x” es un comando de unix que nos permite ver el contenido hexadecimal de cualquier fichero. Alguien que sepa quizás lo pueda hacer con el comando “debugger” de ms-dos.

El caso es que las ocho primeras cifras hexadecimales del fichero son CAFE BABE (cafecito para los amigos). Si lo haces desde un ordenador con micro de intel, verás las sílabas al revés, con lo que no tiene tanta gracia. Cosas del little-endian y el big-endian.

0000000000 FECA BEBA 0000 3100 5200 000A 0013 0732
0000000020 3300 000A 0002 0A34 1100 3500 0007 0936
0000000040 1100 3700 0007 0A38 0700 3200 0008 0A39

Jan 30

.htaccess y .htpasswd

Ultimamente andaba con ganas de hacer algo con PHP. Una de las tonterías que se me había ocurrido, aprovechando que estoy moviendo todas las páginas de mi web de html a PHP, es hacer un pequeño contador de visitas. Inicialmente, simplemente guardaría en base de datos el número de veces que se visualiza cada página de mi web.

Uno de los problemas que se me plantea es ¿dónde pongo el usuario y password de la base de datos de forma que esté más o menos seguro?.

En principio, poniéndolo en un fichero .php como dos variables, por ejemplo $user=’usuario” y $password=’password’ parece que es relativamente seguro. Al pedir el fichero php al servidor, este lo interpreta, con lo que en el navegador no se ve ningún resultado.

Como medida de seguridad, se me había ocurrido que se puede poner ese fichero .php con el usuario y la password en un directorio protegido. Sé desde hace tiempo que si en un directorio que forma parte del sitio web ponemos un fichero .htaccess así

Deny from all

entonces el servidor no entregará ese fichero a nadie externo al servidor. Si alguien intenta ver desde el navegador o hacer un include desde un fichero .php, el servidor le dirá que no tiene permisos.

Hay que puntualizar una cosa. Por defecto y por seguridad, la instalación de Apache no hace ni caso de estos ficheros .htaccess. Un usuario que no sepa puede con el fichero .htaccess dejar bastante desprotegido el sitio web. Para que Apache haga caso de este fichero en un directorio concreto, en el fichero de configuración de Apache debemos añadir lo siguiente

<Directory “path_local_absoluto_al_directorio” >
Options Indexes FollowSymLinks Includes
AllowOverride All
</Directory>

Donde el path_local_absoluto_al_directorio es el path desde el directorio raíz del disco duro donde tengamos la página.

Volviendo al tema de usuario y password, en CristaLab he visto otra buena solución, que es lógica y que no se me había ocurrido y posiblemente más segura. El servidor Apache no sirve páginas fuera del directorio html_public, pero tiene acceso a todos los demás directorios y ficheros del usuario en el sistema operativo. Por ello, se puede poner un fichero con la clave y password en cualquier otro directorio fuera de nuestro directorio html_public.

Finalmente, en ese artículo, también he visto otra cosa que no sabía. Aparte de el usuario y password de la base de datos, es posible proteger directorios completos de forma que sólo se tenga acceso a ellos con el navegador introduciendo un usuario y password.

Para ello, lo primero que hay que hacer es poner los usuarios en un fichero de claves que creemos. Esto se hace creando el fichero .htpasswd, con ese nombre o con cualquier otro nombre, en un directorio que esté fuera del sitio web. Para mis pruebas lo he colocado directamente en D:\ y lo he llamado .htpasswd.

Luego, hay que añadirle usuarios. Para ellos debemos usar el programa htpasswd que viene con Apache. En mi caso, está en el path D:\Aplicaciones\Apache Group\Apache2\Bin. Una vez situado ahí, desde una línea de ms-dos, escribo

htpasswd.exe D:\.htpasswd nombre_usuario

Me pide el password para ese usuario dos veces y listo, ya está creado el usuario para el servidor de Apache. Mirando el fichero .htpasswd podremos verlo, con la clave encriptada.

Luego, en el fichero .htaccess del directorio que quiero proteger pongo

AuthUserFile d:/.htpasswd
AuthName Nombre para la pagina web protegida
AuthType Basic
require user nombre_usuario

Listo. Ahora accedo con el navegador al directorio en cuestión y me pide el usuario y password. Una vez que accedo y hasta que cierre el navegador, tengo acceso a dicho directorio.

Resumiendo y volviendo a mi problema, pondré un fichero.php con nombre raro, fuera del directorio html_public, con dos variables de nombre raro que tengan el usuario y password de base de datos. Donde me haga falta, haré un include de dicho fichero. Espero que algún experto de seguridad me diga si voy mal encaminado…

Jan 29

El Pagerank sigue estando cabra

Hace tiempo pensaba que el Pagerank de google estaba cabra. Ahora acabo de confirmarlo, aunque esta vez de forma favorable para mí.

Este blog lleva … ¿menos de dos meses?. La primera entrada es del 14 de Diciembre de 2006. Bien, pues en estos dos meses escasos veo asombrado que este blog, recién abierto y que nadie enlaza con él, tienen un pargerank de 5.

LLevo años con la página web, siempre he tenido un pagerank de cuatro y nunca he subido de él. Este blog, recién creado, lo ha superado. Nadie enlaza con él, salvo cuatro enlaces que he puesto yo mismo por ahí y los amigos de línea de código. Bueno, nos creeremos que esos escasos enlaces son enlaces de calidad…

Jan 28

proxy google

Hace unos días mencioné que parecía que los de google tenían clasificadas de alguna forma los sitios web de manera que los anuncios de google adsense eran capaces de ver esa clasificación y poner anuncios que no tenían nada que ver con el contenido de una página concreta, pero sí con la temática general del sitio. De hecho, en el post donde lo mencionaba, salían anuncios sobre java cuando en el post no se mencionaba java para nada.

En ojo buscador veo que hay algo de eso. Hay un proxy de google al que los diversos servicios de google, incluido google adsense, consultan para realizar la tarea que tengan que realizar (poner anuncios en este caso). Es fácil que en ese proxy esté clasificado de alguna forma el sitio completo y su temática.

Jan 27

java.sql.Date y java.sql.Timestamp

En las bases de datos se pueden definir procedimientos y funciones a los que podemos llamar desde java. Si hay una función definida llamada una_funcion() que admite de parámetro un LONG y devuelve un VARCHAR, el código java puede ser como este

CallabelStatement st = conexion.prepareCall( “?=call una_funcion(?)”);
st.registerOutParameter(1,Types.VARCHAR ); // El tipo que sea el valor devuelto.
st.setLong(2,clave ); // El tipo que sea el parámetro.
st.execute( );
simbolo = st.getString( 1 );

Llevo haciendo esto en varias ocasiones. Y me he tropezado y dado de bruces con la diferencia  entre java.sql.Date y java.sql.Timestamp.

Resulta que tenemos definida  una función que admite una fecha/hora como parámetro. Es importante tanto la fecha como la hora para la correcta ejecución de la función.

Bien, puesto que en java la clase java.util.Date tiene ambas cosas, por similitud usaba para la llamada a la función la clase java.sql.Date de esta forma

java.util.Date unDate = …;
java.sql.Date fechaHora = new java.sql.Date(unDate);
CallabelStatement st = conexion.prepareCall( “?=call una_funcion(?)”);
st.registerOutParameter(1,Types.VARCHAR );
st.setDate(fechaHora);

Y no funcionaba.

Después de pelearnos un buen rato con el debugger y no sacar nada, al final un tonto System.out.println() para escribir qué valor estabamos pasando a la función nos dio la clave. java.sql.Date SÓLO tiene la fecha, se come la hora.

Pues vaya, si java.sql.Date no vale habrá que probar otra cosa. Probamos con

java.sql.Timestamp fechaHora = new java.sql.Timestamp (unDate);

st.setTimestamp (fechaHora);

y esto funcionó como la seda.

Mirando la API veo que hay java.sql.Date, java.sql.Time y java.sql.Timestamp. El primero es sólo fecha, se come la hora. El segundo supongo que es sólo hora y se come la fecha. El tercero es el bueno, el que tiene fecha y hora.

Son cosas de programar de oido y no leerse los manuales. Algún día aprenderé java.

Jan 25

Tags OBJECT y APPLET

Con el trasiego de la página web para ponerle hojas de estilo y php, me he estado preocupando también de cumplir con el w3c validator, quitar tags obsoletos, etc.

Según veo en w3c.org, el tag APPLET es de los que están obsoletos y en su lugar debe usarse el tag OBJECT, así que todo decidido, según voy poniendo la hoja de estilo a las páginas, voy cambiando los APPLET por OBJECT. Yo, que uso el Firefox, aparentemente todo correcto, estupendo y maravilloso.

Pero … nuevamente “el maligno” hace de las suyas. Cuando ya llevo cambiadas varias páginas con Applets, descubro que Internet Explorer no los muestra. Investigo por internet y efectivamente, no sé qué cosa tiene Internet Explorer con los OBJECT en general, que en muchos sitios recomiendan usar APPLET.

Así que nada, vuelta atrás y rehacer los APPLET. :-(

Jan 24

Error en el cálculo de distancias con GPS

Un compañero de trabajo ha hecho un pequeño programita que va leyendo los datos de un GPS y guardándolos. La idea es poner todo el “aparato” en el coche y ver luego el recorrido realizado, medir distancias, etc.

Para medir distancias, toma la posición del GPS cada dos segundos y calcula la distancia recorrida respecto al punto anterior. Luego va sumando esas distancias. En principio, pensaba que los errores de medida se acabarían compensando. La distancia de más que se mida en un par de medidas debería compensarse con la distancia de menos que se mida en la siguiente.

Sin embargo no es así. Al final los errores se van sumando y siempre la distancia total puede ser del orden del 10% al 15% más de la distancia real recorrida. Mirando por internet se ve que ese es un problema general y además no es fácil de resolver. Los coches (o chismes móviles de más alta gama) que tienen estas opciones de fábrica se fian más de sensores en las ruedas para medir distancias que del GPS.

Lo de la compensación de errores parece lógico. ¿Por qué no es así entonces?.

Pensando un poco en el tema, la suma de estos errores es lógica. Imagina que vamos en línea recta. El error a lo largo de la línea evidentemente más o menos se compensa. El error de más de una medida se compensa más o menos con el error de menos de las siguientes.

Sin embargo, también tenemos errores laterales. Las posiciones que nos da el GPS no caen sobre la línea, sino a los lados de ella, unas veces a un lado, otras a otro. Esto hace que la distancia total al caminar sobre la línea recta haciendo “quiebros” sea más larga que la línea recta. En la figura está más o menos lo que quiero decir.

Errores en medida de GPS

Esta claro que para ir de A a B, el camino rojo es más largo, independientemente de que los errores longitudinales se acaban compensando.

Jan 23

JFrame vs JApplet

Es bastante habitual realizar una aplicación java de la primera forma que se nos ocurra. Si necesitamos una aplicación independiente hacemos que la clase principal de nuestra aplicación herede de JFrame o bien construimos nuestra interface directamente sobre JFrame. Si nuestra aplicación se va a ver en un navegador, hacemos lo mismo, pero heredando o construyendo sobre un JApplet.

También es bastante habitual que luego necesitemos cambiar de aplicación idependiente a Applet o viceversa. Incluso que queramos las dos versiones de nuestro programa.

Una buena solución es contruir toda nuestra aplicación sobre un JPanel, o mejor aún, poner un método al que se le pase un Container y se construya la interface gráfica sobre ese Container. Más o menos así

public class MiAplicacion()
{
public void contruye (Container contenedor);
{
// Se contruye la interface de usuario
contenedor.add (componentes);
}
}

De esta forma, luego podemos hacer una clase Applet con método main() así

public class Principal extends JApplet
{
// Método de inicialización del Applet
public void init ()
{
MiApliacion aplicacion = new MiAplicacion();
// Se contruye la aplicación sobre el Applet.
aplicacion.construye (this);
}

// Método de inicialización como aplicación independiente.
public void main (String [] args)
{
JFrame ventana = new JFrame();
MiApliacion aplicacion = new MiAplicacion();
// Se construye la aplicación sobre el JFrame
aplicacion.construye (ventana.getContentPane());
}
}

De esta forma tenemos todo mezclado en una sola clase. Si metemos Principal en una página html funcionará como un Applet. El navegador se encagará de llamar al método init(). Si lo ejecutamos desde una línea de comandos java Principal, se ejecutará el main() y funcionará como aplicación independiente.

Esto permite además conseguir los recursos de la aplicación (iconos, ficheros y demás) de distinta forma, ya que en un JApplet las imágenes se obtienen con el método applet.getImage(), mientras que un JFrame se puede leer directamente un fichero de imagen. Dejaríamos en la clase Principal la parte de carga de imágenes (recursos) y a MiAplicacion se los pasaríamos con métodos que tuviera adecuados para ello.

Jan 22

Cambio de diseño

Pregunté en un foro por el estilo de la libretita y los postit para mi página web y este blog, pero parece que no gustó mucho.

Teniendo eso en cuenta, que últimamente le estoy pillando el gusto a CSS y que llevo un par de semanas arreglando mis antiguas páginas html para extraer el css y pasarlas a php, pues hoy me entretengo haciendo otro nuevo cambio de look. Este me parece demasiado azul, pero ya seguiré jugando.

Jan 22

ONO

A mediados de Octubre de 2006 me dí de alta con ONO: televisión, teléfono e internet. Ya puse algún comentario sobre ello. Vamos a comentar la situación actual:

  • Internet. De momento bien. Algún corte puntual de vez en cuando, pero nada grave si no se es demasiado exigente. Con lo que cobran debería exigírseles, pero como no hay mucha diferencia con otras opciones de otras compañías, supongo que hay que aguantarse.
  • Televisión. Sigue dando ruido digital (pixelado) de vez en cuando, hasta el punto de dejar de poder verse alguna cadena puntualmente. Pensé que al acabar en Enero la oferta de “todos los canales para todo el mundo” el problema se arreglaría, pero no es así.
  • Teléfono. Por fín, hoy, me han dado de baja de telefónica. El problema es que tenía que firmarles a ONO unos papeles solicitando la baja, cosa lógica por otro lado si pensamos que sin mi consentimiento expreso no deberían poder los de ONO, ni nadie, darme de baja de telefónica. El problema es que al darme de alta en ONO por teléfono, no me dijeron ni me mandaron dichos papeles. Al ir pasando el tiempo, llamé para ver qué pasaba y es entonces cuando me comentan lo de los papeles. Por supuesto, como ya he pagado, no me manda un comercial a casa, sino que me envían los papeles por correo y los devuelvo firmados por correo. Ya no sé si es cosa de correos o interna de ellos, el caso es que todo el trasiego de cartas ha tardado mes y medio. Eso sí, una vez que reconocieron que les había llegado, han tardado unos pocos días. Me avisaron el Viernes de que hoy a las once me tramitaban la baja y hoy a las once lo han hecho.

Lo último del teléfono me ha dado mucho que pensar. Lo ineficientes que son para tramitar el papeleo, pero lo eficientes que son una vez que se ponen.

Lo de la tele me lo pensaré. Para lo que echan y la veo, si encima se ve mal, será cuestión de darse de baja.