martes, 1 de octubre de 2013

Probabilidades y palabrotas

Situación típica: escribimos un fragmento de código para generar contraseñas más o menos aleatorias:

$src = 'abcdefghijkmlnopqrstuvwxyz0123456789';
$new = "";
$x = 0;
while($x < 8){
  $new .= substr($src, rand(0, strlen($src)-1), 1);
  $x++;
}

Estas líneas generan una cadena aleatoria de 8 caracteres alfanumérico. ¿Cuál es la probabilidad de que salga alguna palabrota? Tengo que recordar mis rudimentos de combinatoria, pero podemos asegurar que es una probabilidad bastante baja.

Pues bien, por baja que sea, no es cero. Caso verídico: he tenido una queja de una persona que se quejaba de que en la contraseña que le enviamos ponía "puta".

Vamos a comprobarlo mediante fuerza bruta:

<?php

function generarCadena($src, $len) {
    $x = 0;
    $new = "";
    while($x < $len) {
      $new .= substr($src, rand(0, strlen($src)-1), 1);
      $x++;
    }
    return $new;
}

ini_set('display_errors', FALSE);
$opts = getopt('s:l:w:');
if(!$opts['w']) die("-w");
$word = $opts['w'];
$src = isset($opts['s']) ? $opts['s'] : 'abcdefghijkmlnopqrstuvwxyz0123456789';
$len = $opts['l'] && is_numeric($opts['l']) ? (int)$opts['l'] : 8;
$count = 0;

while(true) {
    $new = generarCadena($src, $len);
    if(strpos($new, $word) !== FALSE) {
        die("Encontramos '$word' en la cadena '$new' tras ".number_format($count, 0, ",", ".")." iteraciones.n");
    }
    $count++;
}

?>

En este fragmento de código pedimos una palabra y empezamos a generar cadenas con una longitud de $len a partir de la semilla $src hasta que la encontramos.  Veamos cuánto tarda en aparecer la palabra "puta":

david@localhost:~/dev$ while(true); do php testRandomString.php -w puta  -l 8; done
Encontramos 'puta' en la cadena 'putarzd7' tras 113.588 iteraciones.
Encontramos 'puta' en la cadena 'tputag94' tras 745.111 iteraciones.
Encontramos 'puta' en la cadena 'oputa6in' tras 540.359 iteraciones.
Encontramos 'puta' en la cadena 'vputazze' tras 321.592 iteraciones.
Encontramos 'puta' en la cadena 'putarx1t' tras 331.196 iteraciones.
Encontramos 'puta' en la cadena 'puta75cs' tras 782.809 iteraciones.
Encontramos 'puta' en la cadena 'crputazr' tras 180.502 iteraciones.
Encontramos 'puta' en la cadena '13qqputa' tras 56.523 iteraciones.
Encontramos 'puta' en la cadena 'g1puta3n' tras 12.595 iteraciones.
Encontramos 'puta' en la cadena '6fg6puta' tras 190.036 iteraciones.
Encontramos 'puta' en la cadena 'oputayon' tras 644.111 iteraciones.
Encontramos 'puta' en la cadena 'ckputako' tras 170.121 iteraciones.
Encontramos 'puta' en la cadena 'jyputaob' tras 285.211 iteraciones.
Encontramos 'puta' en la cadena 'avputao5' tras 864.466 iteraciones.
Encontramos 'puta' en la cadena '88putaqa' tras 605.127 iteraciones.
Encontramos 'puta' en la cadena '9putawoi' tras 101.390 iteraciones.
Encontramos 'puta' en la cadena 'oputaik1' tras 15.688 iteraciones.
Encontramos 'puta' en la cadena '7puta940' tras 19.865 iteraciones.
Encontramos 'puta' en la cadena 'fjputajw' tras 355.393 iteraciones.
Encontramos 'puta' en la cadena 'putafpkn' tras 273.997 iteraciones.
Encontramos 'puta' en la cadena '7asputa5' tras 4.631 iteraciones.
Encontramos 'puta' en la cadena 'eputartt' tras 484.259 iteraciones.
Encontramos 'puta' en la cadena 'gz5putax' tras 266.215 iteraciones.
Encontramos 'puta' en la cadena '4ftpputa' tras 834.145 iteraciones.
Encontramos 'puta' en la cadena 'ryoputas' tras 318.049 iteraciones.
^C

No es tan improbable como pensábamos. En la línea marcada se ve cómo ha habido un ciclo de ejecuciones en las que sólo han sido necesarias 4.631 iteraciones para que aparezca la palabra que buscamos.

Conclusión: ojo con los generadores de palabras "aleatorios". Pueden generar patrones reconocibles que pueden ofender a algún usuario.

Por curiosidad, también lo he probado con palabras más largas:

david@localhost:~/dev$ while(true); do php testRandomString.php -w zorro -l 8; done
Encontramos 'zorro' en la cadena 'kozorro7' tras 14.560.786 iteraciones.
Encontramos 'zorro' en la cadena 'zorro9v7' tras 1.676.779 iteraciones.
Encontramos 'zorro' en la cadena 'zorro6i3' tras 6.871.325 iteraciones.
^C

david@localhost:~/dev$ while(true); do php testRandomString.php -w cabron -l 8; done
Encontramos 'cabron' en la cadena '0hcabron' tras 935.995.307 interaciones.
^C

lunes, 23 de septiembre de 2013

Metapaquetes para desarrollar y ahorrar tiempo

Una de las funcionalidades más útiles de los sistemas de empaquetamiento de las distribuciones es la creación de paquetes qué sólo listan dependencias. Por ejemplo, el paquete "desktop" lista como dependencias una serie de paquetes.

Podemos crear nuestros propios paquetes y distribuirlos entre las personas que trabajan con nosotros para montar rápidamente una estación de trabajo, servidor, etc.

Es extremadamente sencillo crear nuestros propios metapaquetes, por ejemplo, en un sistema Debian/Ubuntu se hace con el comando equivs-control, que crea una plantilla, se edita esta y luego se crea el paquete con equivs-build.

En la ayuda de Ubuntu viene perfectamente explicado:

https://help.ubuntu.com/community/MetaPackages#Creating_Metapackages

Merece la pena dedicarle 10 minutos.

viernes, 13 de septiembre de 2013

Xscreensaver - BSOD

Me encanta el BSOD que viene como salvapantallas. Resulta que ahora lo empaquetan por separado. El WARNING no tiene desperdicio.

 

yo@localhost:~$ apt-cache show xscreensaver-screensaver-bsod
Package: xscreensaver-screensaver-bsod
Priority: optional
Section: universe/x11
Installed-Size: 524
Maintainer: Ubuntu Developers
Original-Maintainer: Jose Luis Rivas
Architecture: amd64
Source: xscreensaver
Version: 5.15-2ubuntu1
Replaces: xscreensaver-data-extra (<< 5.10-4)
Depends: libc6 (>= 2.7), libgdk-pixbuf2.0-0 (>= 2.22.0), libglib2.0-0 (>= 2.12.0), libx11-6, libxext6, libxmu6, libxt6, xscreensaver-data-extra
Conflicts: xscreensaver-data-extra (<< 5.10-4)
Filename: pool/universe/x/xscreensaver/xscreensaver-screensaver-bsod_5.15-2ubuntu1_amd64.deb
Size: 151922
MD5sum: c9b4848ea9a0a6f651af766bc83e984d
SHA1: 14debe28946f9ccbf010f54588b8852bedf43c26
SHA256: a800c369299009e2dd36f833cd5c092e5893e0e78a4026b5e7c00469e6a0523b
Description-en: BSOD hack from XScreenSaver
 This package ships the hack BSOD that shows the popular Blue Screens of Death
 from several OSes including BSD, Windows, Linux, Solaris, Apple and much more.
 .
 WARNING: This screensaver could be confused with a real BSOD and could lead an
 user to reboot the machine with consequences like data loss.

Homepage: http://www.jwz.org/xscreensaver/
Description-md5: fa1f8a3ec4ff356bc203ff76a929e702
Bugs: https://bugs.launchpad.net/ubuntu/+filebug
Origin: Ubuntu

miércoles, 24 de julio de 2013

La caída de "The Old Reader"

Antes de cerrar Google Reader busqué algún servicio alternativo y encontré The Old Reader. Importó mis suscripciones bien y desde hace varios meses soy un feliz usuario.
Hasta este domingo, que estaba caído. Parecía que estaban haciendo un mantenimiento. En el momento en que escribo esto llevan más de 72 horas sin servicio. Han tenido graves problemas con los servidores y tienen que restaurar la base de datos desde el último backup.


Esta entrada no es una queja, faltaría más. Sé lo que supone restaurar desde un backup del orden de decenas de Gigas. Su base de datos parece que rondaba un Tera, así que el proceso debe ser una pesadilla.



Sólo me pregunto si The Old Reader sobrevivirá a esta caída. Los usuarios no solemos ser muy pacientes. Me encantaría saber las cifras de nuevos usuarios de otros servicios similares en los últimos días.
Les deseo un pronto restablecimiento. Desconozco la fuente de financiación de The Old Reader, pero me temo que peligre.

Actualización (29/07/2013): 
Parezco un cuervo de mal agüero, pero es que lo de la semana pasada pintaba muy mal. The Old Reader cierra y se mantendrá como un servicio privado para unas pocas cuentas escogidas:
http://blog.theoldreader.com/post/56798895350/desperate-times-call-for-desperate-measures

Actualización final:
Parece que todo vuelve a la normalidad, vuelven a funcionar en abierto. Bienvenidos sean.

lunes, 1 de julio de 2013

¿SQL en la URL?

¿A que suena un poco feo? ¿No es una burrada tener una URL en la que, aparentemente, va la consulta?

Pues el DFP SB (de Google), funciona con estas URLs. Curioso.

viernes, 21 de junio de 2013

Diarios esclavos del SEO

Es lamentable y penoso. Un día alguien se dio cuenta de que poniendo en el titular de la noticia la palabra "Google", la palabra "doodle" y el tema del día se ganaban bastantes visitas.
Ahora, pinchar en el doodle apesta.


miércoles, 19 de junio de 2013

UTF8 sí o sí

Función susceptible de mejora, pero extremadamente útil.

/**
* Sirve en UTF-8 sí o sí.
*/
function supericonv($txt) {
    $txt1 = iconv('ISO-8859-15', 'UTF-8', $txt);
    $retVal = strpos($txt1, 'Ã') === FALSE ? $txt1 : $txt;
    $retVal = str_replace(array("¿", "»", "«"), array("¿", "»", "«"), $retVal);
    return $retVal;
}

lunes, 15 de abril de 2013

Reflotando un blog medio abandonado

Varios meses han pasado desde el último apunte. Realmente, mantener un blog vivo cuesta trabajo. Leyendo las últimas entradas, más que un blog parece un bloc de notas (¿cómo era esto del Guake? ¿y aquel shell-script para hacer lo otro?).

Voy a intentar reflotar el blog, sabiendo que va a suponerme un esfuerzo encontrar todas las semanas algo sobre lo que escribir y aportar algo que no sea un copia-pega de lo que se está comentando.

Si no hacemos este esfuerzo, al final los blogs también acabarán desapareciendo como ya lo hicieron las "news".