Bueno, ya veo que hace más de dos meses que no asomo el pelo por aquí. El caso es que he estado ocupado y después de una temporada, por fin puedo volver a CakePHP un rato.
Estoy trabajando en la parte de gestión de usuarios de una aplicación y se me ocurrió que necesitaba un generador de contraseñas para automatizar la creación de las mismas al dar de alta manual o automáticamente a usuarios (no creo que esta aplicación lleve autorregistro).
Mis usuarios odian las contraseñas puramente aleatorias del tipo ajku87hsdf6, así que pensé en utilizar uno de esos generadores de contraseñas legibles o memorizables. No encontré ninguno que me gustase, así que acabé escribiéndolo y esta es la segunda versión (muy difícil no es).
Lo de las contraseñas memorizables es bastante sencillo. Se trata de series de letras construidas de tal modo que parecen palabras y son bastante fáciles de pronunciar y memorizar por humanos. Por ejemplo:
hanicu,
corchuela o
gafimocho.
La base del generador es la construcción de sílabas válidas en español (en este caso), combinando una consonante (o grupo consonántico) con una vocal y opcionalmente con otra consonante válida para finalizar una sílaba.
He añadido un factor de fortaleza que afecta a todo el proceso de generación de la contraseña aumentando la probabilidad de que se generen sílabas con más letras. Esto se traduce en claves más largas, con más posibilidad de repetición de caracteres, etc.
Algunas mejoras posibles serían la posibilidad de convertir al azar algunas letras en mayúsculas o incorporar más caracteres (por ejemplo los acentuados).
El uso de la función es muy simple:
$nuevaClave = claveLegible ();
Lo anterior nos daría claves de fortaleza media
o indicando la fortaleza deseada:
// baja, pasar 'l' de 'low'
$nuevaClave = claveLegible('l');
//alta, pasar 'h', de 'high'
$nuevaClave = claveLegible('h');
<?php
/**
* Genera una clavve legible que se puede memorizar por humanos con mayor facilidad
* sin que por eso se pierda demasiada seguridad
* @param $fortaleza: 'l' (baja), 'm' (media), 'h' (alta). Por defecto es 'm'. Indica
* la solidez teórica de la contraseña generada (más larga y con palabras más difíciles
* de localizar en un diccionario0)
*
* @return string La clave generada
* @author Frankie
**/
function claveLegible($fortaleza = 'm') {
// Preparamos los parámetros de la generación a partir de la indicación de fortaleza
$fortaleza = strtolower($fortaleza);
if ($fortaleza == 'h') {
$factor = 0;
$numeroSilabas = 5;
} elseif ($fortaleza == 'l' ) {
$factor = 4;
$numeroSilabas = 3;
} else {
$factor = 2;
$numeroSilabas = 4;
}
// Fuentes de los caracteres, si quieres modificar la probabilidad de cada uno, añade los que desees
$consonantes = array('b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'ñ', 'p', 'q', 'r', 's', 't', 'v', 'w', 'x', 'y', 'z', ' ');
$grupos = array('b', 'bl', 'br', 'c', 'ch', 'cl', 'cr', 'd', 'f', 'fl', 'fr', 'g', 'h', 'j', 'k', 'l', 'll', 'm', 'n', 'ñ', 'p', 'pr', 'pl', 'q', 'r', 's', 't', 'tr', 'v', 'w', 'x', 'y', 'z', ' ');
$vocales = array('a', 'e', 'i', 'o', 'u');
$diptongos = array('a', 'e', 'i', 'o', 'u', 'ai', 'au', 'ei', 'eu', 'ia', 'ie', 'io', 'oi', 'ou', 'ua', 'ue', 'uo');
$finales = array(' ', 'n', 'l', 's', 'r', 'd');
// Generación de la contraseña. Cada sílaba se construye con una consontante o grupo inicial, una vocal y una consonante final. Se introduce un factor de aleatoriedad regulado por la fortaleza para generar sílabas más o menos simples.
$clave = '';
for ($i=0; $i < $numeroSilabas; $i++) {
$consonante = rand(0,$factor) ? $consonantes[rand(0, count($consonantes)-1)] : $grupos[rand(0, count($grupos)-1)] ;
$vocal = rand(0, 2*$factor) ? $vocales[rand(0, count($vocales)-1)] : $diptongos[rand(0, count($diptongos)-1)];
$final = rand(0, 4*$factor) ? '' : $finales[rand(0, count($finales)-1)];
$clave .= trim($consonante . $vocal . $final);
}
return $clave;
}
// Test
//
// for ($i=0; $i < 20; $i++) {
// echo claveLegible('m') . chr(10);
// }
?>
Addenda: Uso en CakePHPYo he creado una carpeta Utilidades bajo Vendors y he puesto la función en un archivo clave_legible.php.
Cuando necesites usarla en Cake, no tienes más que cargarla con una llamada
vendor('utilidades/clave_legible')