简体   繁体   中英

A way to check if a string contains a character from a specific substring

I'm doing a coding boot camp and our objective is to set up a password generator that a user selects which type of characters (lowercase, uppercase, number, and special) and a length and it provides them with a random secure password.

I am able to get all aspects of this to work, aside from an important part of the assignment which is that the generated password must include each character the user selected. It's currently grabbing at random, so it's not always guaranteed if you choose all 4 criteria that they will all appear. How can I validate this?

const lowCaseArr = "abcdefghijklmnopqrstuvwxyz";
const upCaseArr = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const numeralArr = "1234567890";
const specialArr = "!@#$%^&*";

function getLength() {
    while (true) {
        var userLength = parseInt(prompt("How many numbers, between 8 and 128, would you like to use? (Enter 0 to cancel)"));
        if (userLength == 0) {
            return 0;
        } else if (userLength > 128 || userLength < 8) {
            alert("You must enter a number between 8-128.");
        } else if (userLength <= 128 && userLength >= 8) {
            alert("Great! Your have selected a password with " + userLength + " characters.");
            return userLength;
        }
    } 
}

function randChar(passwordCharacters) {
    return passwordCharacters.charAt(Math.floor(Math.random() * passwordCharacters.length));
}

function makePassword(userLength, passwordCharacters) { 
    var securePassword = "";
    for (i = 0; i < userLength; i++) {    
        securePassword += randChar(passwordCharacters);
    }
    return securePassword;
}

function generatePassword() {
    var userLength = getLength();
    if (userLength == 0) {
        return "User Cancelled Request";
    }


    var passwordCharacters = "";
    var askLowerCase = confirm("Would you like to include lower case characters? (a, b, c)");
    if (askLowerCase !== true) {
        alert("Got it. No lower case characters will be included.");
    } else {
        alert("Great! Your password will include lower case characters!");
        passwordCharacters += lowCaseArr;
    }

    var askUpperCase = confirm("Would you like to include upper case characters? (A, B, C)");
    if (askUpperCase !== true) {
        alert("Got it. No upper case characters will be included.");
    } else {
        alert("Great! Your password will include upper case characters!");
        passwordCharacters += upCaseArr;
    }

    var askNumerals = confirm("Would you like to include numeral characters? (1, 2, 3)");
    if (askNumerals !== true) {
        alert("Got it. No numeral characters will be included.");
    } else {
        alert("Great! Your password will include numeral characters!");
        passwordCharacters += numeralArr;
    }

    var askSpecial = confirm("Would you like to include special characters? (~, !, @)");
    if (askSpecial !== true) {
        alert("Got it. No special characters will be included.");
    } else {
        alert("Great! Your password will include special characters!");
        passwordCharacters += specialArr;
    }    

    var basePassword = makePassword(userLength, passwordCharacters);

    var securePassword = validateOptions(basePassword, askLowerCase, askUpperCase, askNumerals, askSpecial);
    return securePassword;

}

var generateBtn = document.querySelector("#generate");

function writePassword() {
    var password = generatePassword();
    var passwordText = document.querySelector("#password");

    passwordText.value = password;
}

generateBtn.addEventListener("click", writePassword);

My thought is to create a function that validates password, I'm just not sure what the best logic is here.

function validateOptions(basePassword, askLowerCase, askUpperCase, askNumerals, askSpecial) {

    var securePassword = basePassword;

    // while (missing requirements) {
    // Validate that all selected characters have been included

    //  if securePassword does not contain lowercase, 
    //      then replace a random char in string with lowercase character
    //  if securePassword does not contain uppercase,
    //      then replace a random char in string with uppercase character
    //  if securePassword does not contain numbers,
    //      then replace a random char in string with numeral character
    //  if securePassword does not contain special characters,
    //      then replace a random char in string with a special character
    //  }
    
    return securePassword;
}

Rather than alter the password after the fact, you can generate it properly from the beginning by ensuring it meets all the constraints.

I've taken pieces of your code to produce a standalone function makeSecurePassword() which accepts several arguments: userLength , askLowerCase , askUpperCase , askNumerals , askSpecial . It returns a password of the requested userLength , containing only the types of characters requested. It uses your randChar() helper function.

var securePassword = makeSecurePassword( 10, true, true, true, true );

console.log(securePassword);

// Return a random character from passwordCharacters:
function randChar(passwordCharacters) {
    return passwordCharacters.charAt(Math.floor(Math.random() * passwordCharacters.length));
}

function makeSecurePassword( userLength, askLowerCase, askUpperCase, askNumerals, askSpecial ) {
    const lowCaseArr = "abcdefghijklmnopqrstuvwxyz";
    const upCaseArr = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    const numeralArr = "1234567890";
    const specialArr = "!@#$%^&*";

    var password = [];

    // Decide which chars to consider:
    charArray = [];
    if ( askLowerCase ) {
        charArray.push( lowCaseArr );
    }
    if ( askUpperCase ) {
        charArray.push( upCaseArr );
    }
    if ( askNumerals ) {
        charArray.push( numeralArr );
    }
    if ( askSpecial ) {
        charArray.push( specialArr );
    }
    
    let x = 0; // index into charArray
    for ( var i=0; i < userLength; i++ ) {
        var a = charArray[x]; // Which array of chars to look at

        // Insert at random spot:       
        password.splice( password.length, 1, randChar( a ) );

        // Pick next set of chars:
        if ( ++x >= charArray.length ) {
            x = 0; // Start with the first set of chars if we went past the end
        }
    }

    return password.join(''); // Create a string from the array of random chars
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM