javascript - Is my password generating function inefficient? -
i have javascript password generating function. right i'm discarding passwords don't match selected specifications. example if password doesn't contain numbers, discard , generate new 1 hopping 1 have number in it. doesn't seem efficient performance vise, @ least not me.
is there better way implement forcing of specific characters in generated password?
also i'm planning add password can forced contain special characters. if current way, have have regex check if password contains special characters , if not throw way (again doesn't seem efficient 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 = ""; (var = 0, n = charset.length; < 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 last one. trunkated , regenerated.'); } retval += gen; } // if charset contains numbers make sure atleast 1 number if ( (retval.match(/\d+/g) == null) && (charset.match(/\d+/g) != null)) { console.log('password generated 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')));
you use this. using method allows create multiple key sets , using simple option attribute can switch these keysets in , out of the password generation, along setting length or choosing generate hex password.
function isobject(value) { return object.prototype.tostring.call(value) === '[object object]'; } function assign(target, source) { (var prop in source) { if (source.hasownproperty(prop)) { target[prop] = source[prop]; } } return target; } function shuffle(obj) { var = obj.length; var rnd, tmp; while (i) { rnd = math.floor(math.random() * i); -= 1; tmp = obj[i]; obj[i] = obj[rnd]; obj[rnd] = tmp; } return obj; } function generatepassword(options) { var opts = isobject(options) ? assign({}, options) : {}; var keyspace = ''; if (opts.hex) { keyspace = '0123456789abcdef'; if (opts.uppercase) { keyspace = keyspace.touppercase(); } } else { if (opts.alpha) { keyspace += 'abcdefghijklmnopqrstuvwxyz'; } if (opts.uppercase) { keyspace += 'abcdefghijklmnopqrstuvwxyz'; } if (opts.numeric) { keyspace += '0123456789'; } if (opts.punctuation) { keyspace += "`!\"?$?%^&*()_-+={[}]:;@'~#|\\<,>.?/"; } } if (keyspace.length - 1 < 0) { return ''; } opts.size = opts.size >>> 0 || 16; if (opts.size < 5) { opts.size = 5; } else if (opts.size > 100) { opts.size = 100; } return shuffle(keyspace.split('')).join('').slice(0, opts.size); } var password = generatepassword({ alpha: true, uppercase: true, numeric: true, punctuation: true }); console.log(password);
other options hex generation size length
you modify take string of special characters want use.
update: here more complex example enforces number of each type of chosen characters , works similar above simple example.
function isobject(value) { return object.prototype.tostring.call(value) === '[object object]'; } function assign(target, source) { (var prop in source) { if (source.hasownproperty(prop)) { target[prop] = source[prop]; } } return target; } function shuffle(obj) { var = obj.length; var rnd, tmp; while (i) { rnd = math.floor(math.random() * i); -= 1; tmp = obj[i]; obj[i] = obj[rnd]; obj[rnd] = tmp; } return obj; } function getxchars(string, number) { var str = typeof string === 'string' ? string : ''; var num = typeof number === 'number' && number > 0 ? number : 0; var array = []; var = str.length; var rnd; while (i && array.length < num) { rnd = math.floor(math.random() * i); -= 1; array.push(str.charat(rnd)); } return array; } function generatepassword(opts) { var opts = isobject(opts) ? assign({}, opts) : {}; var keyspace = ''; var result = []; var = 0; var tmp; if (typeof opts.hex === 'number' && opts.hex > 0) { += opts.hex; keyspace = '0123456789abcdef'; if (opts.uppercase === true) { keyspace = keyspace.touppercase(); } result = result.concat(getxchars(keyspace, opts.hex)); } else { if (typeof opts.alpha === 'number' && opts.alpha > 0) { += opts.alpha; tmp = 'abcdefghijklmnopqrstuvwxyz'; keyspace += tmp; result = result.concat(getxchars(tmp, opts.alpha)); } if (typeof opts.uppercase === 'number' && opts.uppercase > 0) { += opts.uppercase; tmp = 'abcdefghijklmnopqrstuvwxyz'; keyspace += tmp; result = result.concat(getxchars(tmp, opts.uppercase)); } if (typeof opts.numeric === 'number' && opts.numeric > 0) { += opts.numeric; tmp = '0123456789'; keyspace += tmp; result = result.concat(getxchars(tmp, opts.numeric)); } if (typeof opts.punctuation === 'number' && opts.punctuation > 0) { += opts.punctuation; tmp = "`!\"?$?%^&*()_-+={[}]:;@'~#|\\<,>.?/"; keyspace += tmp; result = result.concat(getxchars(tmp, opts.punctuation)); } } if (keyspace.length === 0) { return keyspace; } opts.size = opts.size >>> 0 || 16; if (opts.size < 5) { opts.size = 5; } else if (opts.size > 100) { opts.size = 100; } result = result.concat(getxchars(keyspace, opts.size - i)); return shuffle(result).join(''); } var password = generatepassword({ alpha: 1, uppercase: 1, numeric: 1, punctuation: 1 }); console.log(password);
update: promised here possible replacement math.random. if window.crypto.getrandomvalues available use it, otherwise falls math.random.
function random() { if (window.crypto && typeof window.crypto.getrandomvalues === 'function') { console.log('using crypto'); var array = new uint32array(1); window.crypto.getrandomvalues(array); return array[0] / (math.pow(2, 32) + 1); } console.log('using random'); return math.random(); } console.log(random());
Comments
Post a Comment