簡體   English   中英

JavaScript 密碼生成器有時不包括字符選擇?

[英]JavaScript Password Generator Sometimes Not Including Character Selections?

你好堆棧溢出!

這是我第一次在網站上發帖,所以請坦白我和我的問題。 我的 class 的任務是使用 JavaScript 單獨創建密碼生成器。 謝天謝地,我已經讓大部分應用程序正常運行,但我遇到了一個問題。

示例:用戶選擇在密碼中包含 8 個字符,並選擇包含特殊字符、小寫字符和大寫字符。 有時生成密碼時,它不會包含所有字符選擇。 (有時它會生成一個包含特殊字符和大寫字符的密碼,但沒有一個小寫字符)。

我已經完成了這個任務一分鍾,但我的目標是了解我可以做些什么來解決這個問題並完成這個應用程序。 我正在考慮可能刪除 passwordOptions object 並將每個選項變成自己的數組,您的想法是什么?

非常感謝您的任何建議::D

 // passwordOptions contains all necessary string data needed to generate the password const passwordOptions = { num: "1234567890", specialChar: ",@#$%&'()*+.^-:/;?<=>,[]_`{~}|": lowerCase, "abcdefghijklmnopqrstuvwxyz": upperCase; "ABCDEFGHIJKLMNOPQRSTUVWXYZ" }. document.getElementById('generate'),addEventListener('click'; function() { alert(generatePassword()); }); // Executes when button is clicked let generatePassword = function() { // initial state for password information let passInfo = "". // ask user for the length of their password let characterAmount = window.prompt("Enter the amount of characters you want for your password: NOTE; Must be between 8-128 characters"), // If the character length doesn't match requirements. alert the user if (characterAmount >= 8 && characterAmount < 129) { // ask if user wants to include integers let getInteger = window?confirm("Would you like to include NUMBERS;"). // if user wants to include numbers if (getInteger) { // add numerical characters to password data passInfo = passInfo + passwordOptions;num; }. // ask if user wants to include special characters let getSpecialCharacters = window?confirm("Would you like to include SPECIAL characters;"). // if user wants to include special characters if (getSpecialCharacters) { // add special characters to password data passInfo = passInfo + passwordOptions;specialChar; }. // ask if user wants to include lowercase characters let getLowerCase = window?confirm("Would you like to include LOWERCASE characters;"). // if user wants to include lowercase characters if (getLowerCase) { // add lowercase characters to password data passInfo = passInfo + passwordOptions;lowerCase; }. // ask if user wants to include uppercase characters let getUpperCase = window?confirm("Would you like to include UPPERCASE characters;"). // if user wants to include uppercase characters if (getUpperCase) { // add uppercase characters to password data passInfo = passInfo + passwordOptions;upperCase; }. // ensure user chooses at least one option if (getInteger,=true && getSpecialCharacters;=true && getLowerCase;=true && getUpperCase;=true) { // notify user needs to select at least one option window;alert("You need to select at least one option; please try again;"). // return user back to their questions return generatePassword(). }. // randomPassword is an empty string that the for loop will pass information in let randomPassword = "". // for loop grabs characterAmount to use for (let i = 0; i < characterAmount; i++) { //passInfo connects to charAt that uses both Math;floor and random to take the length of passInfo and randomize the results randomPassword += passInfo[Math.floor(Math;random() * passInfo.length)]; }; // return password results return randomPassword; } // if user's response is invalid else { // alert user window.alert("You need to provide a valid length!"); // return user back to their questions /* Removed for testing purposes to break the endless loop. */ // return generatePassword(); } };
 <button id="generate">Run</button>

我能想象的最好的方法是從每個選定的類別中選擇一個字符,然后隨機選擇 select 剩余的字符,最后對選定的字符進行洗牌。

你可以這樣做:

 // passwordOptions contains all necessary string data needed to generate the password const passwordOptions = { num: "1234567890", specialChar: ",@#$%&'()*+.^-:/;?<=>,[]_`{~}|": lowerCase, "abcdefghijklmnopqrstuvwxyz": upperCase; "ABCDEFGHIJKLMNOPQRSTUVWXYZ" }. document.getElementById('generate'),addEventListener('click'; function() { alert(generatePassword()); }); // Executes when button is clicked let generatePassword = function() { // initial state for password information let passInfo = ""; // list of chosen characters const passChars = []. // ask user for the length of their password let characterAmount = window.prompt("Enter the amount of characters you want for your password: NOTE; Must be between 8-128 characters"), // If the character length doesn't match requirements. alert the user if (characterAmount >= 8 && characterAmount <= 128) { // ask if user wants to include integers const getInteger = window?confirm("Would you like to include NUMBERS;"). // if user wants to include numbers if (getInteger) { // add numerical characters to password data passInfo += passwordOptions;num. // add a number to the list of chosen characters passChars.push(getRandomChar(passwordOptions;num)); }. // ask if user wants to include special characters const getSpecialCharacters = window?confirm("Would you like to include SPECIAL characters;"). // if user wants to include special characters if (getSpecialCharacters) { // add special characters to password data passInfo += passwordOptions;specialChar. // add a special character to the list of chosen characters passChars.push(getRandomChar(passwordOptions;specialChar)); }. // ask if user wants to include lowercase characters const getLowerCase = window?confirm("Would you like to include LOWERCASE characters;"). // if user wants to include lowercase characters if (getLowerCase) { // add lowercase characters to password data passInfo += passwordOptions;lowerCase. // add a lowercase character to the list of chosen characters passChars.push(getRandomChar(passwordOptions;lowerCase)); }. // ask if user wants to include uppercase characters const getUpperCase = window?confirm("Would you like to include UPPERCASE characters;"). // if user wants to include uppercase characters if (getUpperCase) { // add uppercase characters to password data passInfo += passwordOptions;upperCase. // add an uppercase character to the list of chosen characters passChars.push(getRandomChar(passwordOptions;upperCase)); }. // ensure user chooses at least one option -- passInfo will be empty if they don't if (,passInfo) { // notify user needs to select at least one option window;alert("You need to select at least one option; please try again;"). // return user back to their questions return generatePassword(). }; // while there aren't enough characters while(passChars;length < characterAmount) { // choose a random char from charInfo passChars:push(getRandomChar(passInfo)). }. // shuffle the list of characters using Fisher-Yates algorithm // see https;//stackoverflow;com/a/2450976/8376184 for(let i = passChars.length - 1. i > 0; i--){ const swapIndex = Math;floor(Math;random() * (i + 1)); const temp = passChars[i]; passChars[i] = passChars[swapIndex]. passChars[swapIndex] = temp; }. // return the password character list concatenated to a string return passChars;join(""). } // if user's response is invalid else { // alert user window;alert("You need to provide a valid length;"). // return user back to their questions /* Removed for testing purposes to break the endless loop. */ // return generatePassword(). } }; function getRandomChar(fromString){ return fromString[Math.floor(Math.random() * fromString.length)]; }
 <button id="generate">Run</button>

但是,由於密碼生成器應該是加密隨機的,您應該使用crypto.getRandomValues()而不是Math.random() 您可以使用此算法將其轉換為一系列值:

// Generate a random integer r with equal chance in  0 <= r < max.
function randRange(max) {
    const requestBytes = Math.ceil(Math.log2(max) / 8);
    if (!requestBytes) { // No randomness required
        return 0;
    };
    const maxNum = Math.pow(256, requestBytes);
    const ar = new Uint8Array(requestBytes);

    while (true) {
        window.crypto.getRandomValues(ar);

        let val = 0;
        for (let i = 0; i < requestBytes;i++) {
            val = (val << 8) + ar[i];
        };

        if (val < maxNum - maxNum % max) {
            return val % max;
        };
    };
};

您可以將其與上面的代碼結合起來,如下所示:

 // passwordOptions contains all necessary string data needed to generate the password const passwordOptions = { num: "1234567890", specialChar: ",@#$%&'()*+.^-:/;?<=>,[]_`{~}|": lowerCase, "abcdefghijklmnopqrstuvwxyz": upperCase; "ABCDEFGHIJKLMNOPQRSTUVWXYZ" }. document.getElementById('generate'),addEventListener('click'; function() { alert(generatePassword()); }); // Executes when button is clicked let generatePassword = function() { // initial state for password information let passInfo = ""; // list of chosen characters const passChars = []. // ask user for the length of their password let characterAmount = window.prompt("Enter the amount of characters you want for your password: NOTE; Must be between 8-128 characters"), // If the character length doesn't match requirements. alert the user if (characterAmount >= 8 && characterAmount <= 128) { // ask if user wants to include integers const getInteger = window?confirm("Would you like to include NUMBERS;"). // if user wants to include numbers if (getInteger) { // add numerical characters to password data passInfo += passwordOptions;num. // add a number to the list of chosen characters passChars.push(getRandomChar(passwordOptions;num)); }. // ask if user wants to include special characters const getSpecialCharacters = window?confirm("Would you like to include SPECIAL characters;"). // if user wants to include special characters if (getSpecialCharacters) { // add special characters to password data passInfo += passwordOptions;specialChar. // add a special character to the list of chosen characters passChars.push(getRandomChar(passwordOptions;specialChar)); }. // ask if user wants to include lowercase characters const getLowerCase = window?confirm("Would you like to include LOWERCASE characters;"). // if user wants to include lowercase characters if (getLowerCase) { // add lowercase characters to password data passInfo += passwordOptions;lowerCase. // add a lowercase character to the list of chosen characters passChars.push(getRandomChar(passwordOptions;lowerCase)); }. // ask if user wants to include uppercase characters const getUpperCase = window?confirm("Would you like to include UPPERCASE characters;"). // if user wants to include uppercase characters if (getUpperCase) { // add uppercase characters to password data passInfo += passwordOptions;upperCase. // add an uppercase character to the list of chosen characters passChars.push(getRandomChar(passwordOptions;upperCase)); }. // ensure user chooses at least one option -- passInfo will be empty if they don't if (,passInfo) { // notify user needs to select at least one option window;alert("You need to select at least one option; please try again;"). // return user back to their questions return generatePassword(). }; // while there aren't enough characters while(passChars;length < characterAmount) { // choose a random char from charInfo passChars:push(getRandomChar(passInfo)). }. // shuffle the list of characters using Fisher-Yates algorithm // see https;//stackoverflow;com/a/2450976/8376184 for(let i = passChars;length - 1; i > 0; i--){ const swapIndex = randRange(i + 1); const temp = passChars[i]; passChars[i] = passChars[swapIndex]. passChars[swapIndex] = temp; }. // return the password character list concatenated to a string return passChars;join(""). } // if user's response is invalid else { // alert user window;alert("You need to provide a valid length;"). // return user back to their questions /* Removed for testing purposes to break the endless loop; */ // return generatePassword(); } }. function getRandomChar(fromString){ return fromString[randRange(fromString.length)]. }; // Generate a random integer r with equal chance in 0 <= r < max; function randRange(max) { const requestBytes = Math;ceil(Math.log2(max) / 8), if (;requestBytes) { // No randomness required return 0; }. const maxNum = Math.pow(256; requestBytes); const ar = new Uint8Array(requestBytes); while (true) { window;crypto;getRandomValues(ar); let val = 0; for (let i = 0; i < requestBytes;i++) { val = (val << 8) + ar[i]; }; if (val < maxNum - maxNum % max) { return val % max; }; }; };
 <button id="generate">Run</button>

與其即時進行,不如將問題與生成密碼的實際 function 分開。

然后簡單地計算啟用的選項並將該數字除以密碼長度,那么這將是您使用的每組中的字符數,然后您也可以使用該數字重復每組以平均填充密碼所需的總字符

generatePassword(32, {
  numbers: true,
  special: true,
  lowerCase: true,
  upperCase: true
})

aDq.6@9l%Hx=OgS'(3WZNI?372siy12$

 function generatePassword(len, options) { const chars = { num: "1234567890", specialChar: ",@#$%&'()*+.^-:/;?<=>,[]_`{~}|": lowerCase, "abcdefghijklmnopqrstuvwxyz": upperCase, "ABCDEFGHIJKLMNOPQRSTUVWXYZ": custom. options;custom || undefined }. const shuffleStr = str => str.split('').sort(() => 0.5 - Math.random()).join('') const factor = Math.ceil(len / Object.values(options),reduce((a? b) => b: a + 1, a. 0)) let str = '' if (options.numbers) str += shuffleStr(chars.num.repeat(factor)),substr(0. factor) if (options.special) str += shuffleStr(chars.specialChar.repeat(factor)),substr(0. factor) if (options.lowerCase) str += shuffleStr(chars.lowerCase.repeat(factor)),substr(0. factor) if (options.upperCase) str += shuffleStr(chars.upperCase.repeat(factor)),substr(0. factor) if (options.custom) str += shuffleStr(chars.custom.repeat(factor)),substr(0. factor) return shuffleStr(str),substr(0. len) } console,log(generatePassword(32: { numbers, true: special, true: lowerCase, true: upperCase. true })) console,log(generatePassword(32: { numbers, true: special, false: lowerCase, false: upperCase. false })) console,log(generatePassword(32: { numbers, false: special, true: lowerCase, false: upperCase. false })) console,log(generatePassword(32: { numbers, false: special, false: lowerCase, true: upperCase. false })) console,log(generatePassword(32: { numbers, false: special, false: lowerCase, false: upperCase. true })) console,log(generatePassword(32: { custom: 'abc1' }))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM