Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

angularjs random password generator at least one upper, lower, number and special character

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("");
        };
like image 752
cplus Avatar asked Dec 05 '25 06:12

cplus


2 Answers

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:

  • generating number of lowerCharacters, number of upperCharacters, number of numbers and number of symbols (i.e. 3 lower, 3 upper, 3 numbers, 3 symbols)
  • push proper number of random characters from each array (lowerCharacters, upperCharacters, ...) into array (i.e. passwordArray)
  • shuffle passwordArray
  • join passwordArray

First step may be:

  • noOfLowerCharacters = 0, noOfUpperCharacters = 0, noOfUpperCharacters = 0
  • count number of needed types (1, 2 or 3). Store it in variable noOfneededTypes.
  • take random number from range from 1 to (passwordLength - noOfneededTypes). Store it in variable noOfLowerCharacters.
  • create usedTypeCounter. Set value to 1
  • if addUpper then take random number from range from 1 to (passwordLength - noOfneededTypes + usedTypeCounter - noOfLowerCharacters). Store it in variable noOfUpperCharacters. Increase usedTypeCounter
  • if addNumbers then take random number from range from 1 to (passwordLength - noOfneededTypes + usedTypeCounter - noOfLowerCharacters - noOfUpperCharacters). Store it in variable noOfNumbers.
  • if addSymbols then noOfSymbols = passwordLength - noOfLowerCharacters - noOfUpperCharacters - noOfNumbers

Example 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/

like image 86
Łukasz Avatar answered Dec 07 '25 21:12

Łukasz


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
    }
}
like image 36
Washington Guedes Avatar answered Dec 07 '25 21:12

Washington Guedes



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!