I have this javascript password generating function. Right now I'm discarding passwords that don't match the selected specifications. For example if the password doesn't contain numbers, I discard it and generate a new one hopping that one will have a number in it. This however doesn't seem to be efficient performance vise, at least not to me.
Is there a better way to implement the forcing of specific characters in the generated password?
Also i'm planning to add so that the password can be forced to contain special characters. If I do this the current way, I would have to have some regex to check if the password contains special characters and if not throw it way (again doesn't seem very efficient to me).
function generatePassword(length, charset, nosimilar) {
// default parameters
length = (typeof length === "undefined") ? 8 : length;
charset = (typeof charset === "undefined") ? 'abcdefghjknpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ123456789' : charset;
nosimilar = (typeof similar === "undefined") ? true : nosimilar;
var gen;
retVal = "";
for (var i = 0, n = charset.length; i < length; ++i) {
gen = charset.charAt(Math.floor(Math.random() * n))
if ( (retVal.charAt( retVal.length-1 ) == gen) && (nosimilar)) {
retVal = retVal.substring(0, retVal.length - 1)
retVal += charset.charAt(Math.floor(Math.random() * n))
console.log('Generated character same as the last one. Trunkated and regenerated.');
}
retVal += gen;
}
// if charset contains numbers make sure we get atleast one number
if ( (retVal.match(/\d+/g) == null) && (charset.match(/\d+/g) != null)) {
console.log('Password generated but no numbers found. Regenerating.');
generatePassword(length, charset, nosimilar);
}
return retVal;
}
if ($("#chLetters").prop('checked')) charset += 'abcdefghjknpqrstuvwxyz';
if ($("#chNumbers").prop('checked')) charset += '123456789';
if ($("#chMixedCase").prop('checked')) charset += 'ABCDEFGHJKLMNPQRSTUVWXYZ';
if ($("#chSpecial").prop('checked')) charset += '!@$%&?+*-_';
$("#passgen").text(generatePassword($("#maxLength").val(), charset, $("#chNoSimilar").prop('checked')));