Skip to content

Instantly share code, notes, and snippets.

@stevereich
Created January 25, 2019 05:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stevereich/ddf54efed35adaba1fc405997077b9c9 to your computer and use it in GitHub Desktop.
Save stevereich/ddf54efed35adaba1fc405997077b9c9 to your computer and use it in GitHub Desktop.
Javascript Random Password / String Generator Script
generatePassword = function(args){
// alpha array
var chars = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'],
// numeric array
numArr = [0,1,2,3,4,5,6,7,8,9],
// special character array
sChars = ['!','@','#','$','%','^','&','*','?'];
// set default values of args
var defaults = {};
defaults['len'] = 16;
defaults['eachUnique'] = false;
defaults['minNumeric'] = Math.min(Math.floor(defaults.len/4),numArr.length);
defaults['withSpecChars'] = true;
defaults['minSpecChars'] = Math.min(Math.floor(defaults.len/4),sChars.length);
// if _eachUnique, total numer of available characters (chars.length + numArr.length + sChars.length = 71)
defaults['maxlength'] = chars.length + numArr.length + sChars.length;
// if no arguments are passed, then set args to defaults
args = (typeof args === 'object') ? args : defaults;
// validate user args for type and values, or set to default
// _len is a number greater than zero and if _eachUnique is true, has a max value of total number of available chars (defaults.maxlength), otherwise defaults.len
var _len = (typeof args['len'] === 'number' && args['len'] > 0) ? ((typeof args['eachUnique'] === 'boolean') ? args['eachUnique'] : defaults.eachUnique) ? Math.min(args['len'],defaults.maxlength) : args['len'] : defaults.len;
// throw console warning if we are overwriting their passed argument is requesting unique characters
if(((typeof args['eachUnique'] === 'boolean') ? args['eachUnique'] : defaults.eachUnique) && typeof args['len'] === 'number' && args['len'] > defaults.maxlength){
console.warn('You specified unique characters, but passed a value for len that exceeds the available '+defaults.maxlength+' characters. This value has been reset to '+defaults.maxlength+'.');
}
// a boolean value, else defaults.eachUnique
var _eachUnique = (typeof args['eachUnique'] === 'boolean') ? args['eachUnique'] : defaults.eachUnique,
// any number greater to or equal to zero, else if each unique, user input or number of numbers (numArr.length = 10), otherwise default.minNumeric
_minNumeric = (typeof args['minNumeric'] === 'number' && args['minNumeric'] >= 0) ? (_eachUnique) ? Math.min(args['minNumeric'],numArr.length) : args['minNumeric'] : defaults.minNumeric;
// throw console warning if we are overwriting their passed argument is requesting unique characters
if(_eachUnique && typeof args['minNumeric'] === 'number' && args['minNumeric'] > numArr.length){
console.warn('You specified unique characters, but passed a value for minNumeric that exceeds the available '+numArr.length+' numbers. This value has been reset to '+numArr.length+'.');
}
// a boolean value, else defaults.withSpecChars
var _withSpecChars = (typeof args['withSpecChars'] === 'boolean') ? args['withSpecChars'] : defaults.withSpecChars,
// any number greater to or equal to zero, else if each unique, user input or number of special char (sChars.length = 9), otherwise default.minSpecChars
_minSpecChars = (typeof args['minSpecChars'] === 'number' && args['minSpecChars'] >= 0) ? (_eachUnique) ? Math.min(args['minSpecChars'],sChars.length) : args['minSpecChars'] : defaults.minSpecChars;
// throw console warning if we are overwriting their passed argument is requesting unique characters
if(_eachUnique && typeof args['minSpecChars'] === 'number' && args['minSpecChars'] > sChars.length){
console.warn('You specified unique characters, but passed a value for minSpecChars that exceeds the available '+sChars.length+' characters. This value has been reset to '+sChars.length+'.');
}
// set all variables
// uid is the array that will hold our return
var uid=[],
// this function merges arr2 into arr1
merge = function(arr1,arr2){
var a=(Array.isArray(arr1)) ? arr1 : [],
b=(Array.isArray(arr2)) ? arr2 : [];
return b.reduce( function(coll,item){
coll.push( item );
return coll;
}, a );
},
// a merged array of alpha, numeric, and special characters
thisArr = (_withSpecChars) ? merge(merge(chars,numArr),sChars) : merge(chars,numArr),
// function to randomly shuffle an array
shuffle = function(arr){
var currentIndex = arr.length,
temporaryValue,
randomIndex;
while (0 !== currentIndex) {
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex -= 1;
temporaryValue = arr[currentIndex];
arr[currentIndex] = arr[randomIndex];
arr[randomIndex] = temporaryValue;
}
return arr;
},
// function to determine if a given value is already in a given array
isUnique = function(arr,val){
var rb = true;
try{
for(var i=0; i<arr.length; i++) {
if (arr[i] == val) rb = false;
}
}
catch(e) {
console.error(e.message);
rb = e.message;
}
finally{
return rb;
}
},
// function to pick a single random value from fromArray,
// (and that doesn't exists in toArry if _eachUnique is true)
pick = function(fromArr,toAarr){
var a = shuffle(fromArr),
v = fromArr[Math.floor(Math.random() * fromArr.length)];
if(_eachUnique){
while(!isUnique(toAarr,v)){
v = fromArr[Math.floor(Math.random() * fromArr.length)]
}
}
return v;
},
// criteria that must be possed or array is reshuffled
testCriteria = new RegExp('^[a-zA-Z]'), // must start with letter
// initial value of testCriteria pass
passedTest = false;
// loop to get min special chars first
for(var x=1;x<=_minSpecChars;x++){
if(_withSpecChars){
uid.push(pick(sChars,uid));
uid = shuffle(uid);
}
// end of special char loop
if(x == _minSpecChars){
// loop to get min numeric values
for(var y=1;y<=_minNumeric;y++){
uid.push(pick(numArr,uid));
uid = shuffle(uid);
// end of numeric loop
if(y == _minNumeric){
// continue to add random characters to
// array until request _len is reached
while (uid.length < _len){
uid.push(pick(thisArr,uid));
uid = shuffle(uid);
}
}
}
}
}
// until test is passed... (must begin with an alpha char)
while (!passedTest){
// shuffle array
uid = shuffle(uid);
passedTest = testCriteria.test(uid[0]);
}
// return array as a joined string
var returnStr = uid.join('').toString();
// check for callback function
if('callback' in args && typeof args['callback'] === 'function'){
args['callback'](returnStr)
}
// or set as return
else{
return returnStr;
}
};
// Examples of use
// set as a var
var pw = generatePassword({
len: 64,
eachUnique: false,
minNumeric: 16,
withSpecChars: true,
minSpecChars: 16
}),
widthDefaultPw = generatePassword();
console.log('With Args: ' + pw);
console.log('With No Args (default vals): ' + widthDefaultPw);
// call with callback
generatePassword({
len: 64,
eachUnique: false,
minNumeric: 16,
withSpecChars: true,
minSpecChars: 16,
callback: function(str){
// do something....
console.log('With args adn callback: ' + str)
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment