How can I make this random password generator to generate at least one of the components? Currently, it happens that a number is not included in the generated password, or any of other types is left out. How to make it to generate at least of of the types?
$scope.passwordLength = 12;
$scope.addUpper = true;
$scope.addNumbers = true;
$scope.addSymbols = true;
$scope.createPassword = function(){
var lowerCharacters = ['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'];
var upperCharacters = ['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'];
var numbers = ['0','1','2','3','4','5','6','7','8','9'];
var symbols = ['!', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', ':', ';', '<', '=', '>', '?', '@', '[', '\\', ']', '^', '_', '`', '{', '|', '}', '~'];
var finalCharacters = lowerCharacters;
if($scope.addUpper){
finalCharacters = finalCharacters.concat(upperCharacters);
}
if($scope.addNumbers){
finalCharacters = finalCharacters.concat(numbers);
}
if($scope.addSymbols){
finalCharacters = finalCharacters.concat(symbols);
}
var passwordArray = [];
for (var i = 1; i < $scope.passwordLength; i++) {
passwordArray.push(finalCharacters[Math.floor(Math.random() * finalCharacters.length)]);
};
$scope.password = passwordArray.join("");
};
What you are doing is creating array of all possible characters (finalCharacters) and taking randomly 12 characters of it.
What you need to do is to take at least one random character from each needed array (upperCharacters, numbers, symbols) and shuffle it.
Algorithm example:
lowerCharacters, upperCharacters, ...) into array (i.e. passwordArray)passwordArraypasswordArrayFirst step may be:
noOfLowerCharacters = 0, noOfUpperCharacters = 0, noOfUpperCharacters = 01, 2 or 3). Store it in variable noOfneededTypes.1 to (passwordLength - noOfneededTypes). Store it in variable noOfLowerCharacters. usedTypeCounter. Set value to 1addUpper then take random number from range from 1 to (passwordLength - noOfneededTypes + usedTypeCounter - noOfLowerCharacters). Store it in variable noOfUpperCharacters. Increase usedTypeCounteraddNumbers then take random number from range from 1 to (passwordLength - noOfneededTypes + usedTypeCounter - noOfLowerCharacters - noOfUpperCharacters). Store it in variable noOfNumbers. addSymbols then noOfSymbols = passwordLength - noOfLowerCharacters - noOfUpperCharacters - noOfNumbersExample of implementation:
$scope.passwordLength = 12;
$scope.addUpper = true;
$scope.addNumbers = true;
$scope.addSymbols = true;
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
// shuffle function taken from http://stackoverflow.com/a/12646864/4989081
function shuffleArray(array) {
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = array[i];
array[i] = array[j];
array[j] = temp;
}
return array;
}
$scope.createPassword = function() {
var lowerCharacters = ['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'];
var upperCharacters = ['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'];
var numbers = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
var symbols = ['!', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', ':', ';', '<', '=', '>', '?', '@', '[', '\\', ']', '^', '_', '`', '{', '|', '}', '~'];
var noOfLowerCharacters = 0,
noOfUpperCharacters = 0,
noOfNumbers = 0,
noOfSymbols = 0;
var noOfneededTypes = $scope.addUpper + $scope.addNumbers + $scope.addSymbols;
var noOfLowerCharacters = getRandomInt(1, $scope.passwordLength - noOfneededTypes);
var usedTypeCounter = 1;
if ($scope.addUpper) {
noOfUpperCharacters = getRandomInt(1, $scope.passwordLength - noOfneededTypes + usedTypeCounter - noOfLowerCharacters);
usedTypeCounter++;
}
if ($scope.addNumbers) {
noOfNumbers = getRandomInt(1, $scope.passwordLength - noOfneededTypes + usedTypeCounter - noOfLowerCharacters - noOfUpperCharacters);
usedTypeCounter++;
}
if ($scope.addSymbols) {
noOfSymbols = $scope.passwordLength - noOfLowerCharacters - noOfUpperCharacters - noOfNumbers;
}
var passwordArray = [];
for (var i = 0; i < noOfLowerCharacters; i++) {
passwordArray.push(lowerCharacters[getRandomInt(1, lowerCharacters.length - 1)]);
}
for (var i = 0; i < noOfUpperCharacters; i++) {
passwordArray.push(upperCharacters[getRandomInt(1, upperCharacters.length - 1)]);
}
for (var i = 0; i < noOfNumbers; i++) {
passwordArray.push(numbers[getRandomInt(1, numbers.length - 1)]);
}
for (var i = 0; i < noOfSymbols; i++) {
passwordArray.push(symbols[getRandomInt(1, symbols.length - 1)]);
}
passwordArray = shuffleArray(passwordArray);
return passwordArray.join("");
};
$scope.password = $scope.createPassword();
See working: http://jsfiddle.net/cmoqkkw8/
You can also create random passwords until one of them match your criteria:
function randomPass (length, addUpper, addSymbols, addNums) {
var lower = "abcdefghijklmnopqrstuvwxyz";
var upper = addUpper ? lower.toUpperCase() : "";
var nums = addNums ? "0123456789" : "";
var symbols = addSymbols ? "!#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~" : "";
var all = lower + upper + nums + symbols;
while (true) {
var pass = "";
for (var i=0; i<length; i++) {
pass += all[Math.random() * all.length | 0];
}
// criteria:
if (!/[a-z]/.test(pass)) continue; // lowercase is a must
if (addUpper && !/[A-Z]/.test(pass)) continue; // check uppercase
if (addSymbols && !/\W/.test(pass)) continue; // check symbols
if (addNums && !/\d/.test(pass)) continue; // check nums
return pass; // all good
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With