Elaboré una respuesta con Javascript, porque es a lo que estoy acostumbrado y no se especifica ningún idioma. Estoy seguro de que puede encontrar / crear un análogo en cualquier otro idioma que desee.
En primer lugar, robé una función de Esta respuesta para crear un producto cartesiano. La explicación de los productos cartesianos no está realmente en el alcance de esta pregunta, pero es suficiente para decir que combina matrices de posibles caracteres en matrices de posibles cadenas (muy simplificado).
Bien, entonces la función de ckozl es:
function cartProd(paramArray) {
function addTo(curr, args) {
var i, copy,
rest = args.slice(1),
last = !rest.length,
result = [];
for (i = 0; i < args[0].length; i++) {
copy = curr.slice();
copy.push(args[0][i]);
if (last) {
result.push(copy);
} else {
result = result.concat(addTo(copy, rest));
}
}
return result;
}
return addTo([], Array.prototype.slice.call(paramArray));
}
y el mío es:
function findSubs(string) {
//create a linked list of sub characters
//expect lower case input
subs={
"p":["p","P"],
"a":["a","A","4","@"],
"s":["s","S","$","5"]
}
//create an (initially empty) array to store possible characters in each position
result=[]
for (var i=0;i<string.length;i++) {
result[i]=subs[string.charAt(i)]; //Would be more robust if you added logic here to handle it not being a key in the subs object.
}
/*
so result might look like:
[
["p","P"],
["a","A","4","@"],
["s","S","$","5"],
["s","S","$","5"]
]
for an input of "pass"
*/
return cartProd(result)
}
Honestamente, la función de ckzol hace todo el trabajo pesado aquí. Necesitaría completar la matriz subs antes de usarla, y esto no permite agregar caracteres al final de la cadena (porque parece algo arbitrario).
También tenga en cuenta que alguna vez modifiqué ligeramente la función cartProd, de modo que podamos entregarle una matriz de matrices como parámetros de entrada en lugar de múltiples matrices que sobrecarguen los argumentos.
Editar: también tenga en cuenta que el valor devuelto es una matriz de matrices, por lo que le gustaría iterarlo y para cada elemento e
do e.join("")
.
Edite de nuevo: también tenga en cuenta que podría extenderlo fácilmente para aplicar otras mutaciones a la contraseña. Por ejemplo, si desea agregar un número entre 0 y 99 al final de la cadena, puede insertar una matriz adicional en el final del resultado, que contiene ["0","1","2",...,"99"]
. Podría incluir un elemento vacío ( ""
) en esta matriz para generar también posibilidades que no incluyan el sufijo numérico. La misma lógica podría usarse para agregar un prefijo. Esencialmente, estás creando una matriz de matrices de posibles caracteres en la matriz de resultados, por lo que puedes incluir cualquier mutación que puedas imaginar.