javascripthtmlpasswordspassword-generator

Minimum amount of uppercase chars | Password generator


I'm currently working on a password generator (based on a YT video) and the following is what I have so far.

HTML file:

<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title></title>
    <link rel="stylesheet" href="StyleSheet1.css" />
</head>
<body>
    <div id="password-generator">
        <h1>Password Generator</h1>
        <label for="length">Password Length</label>
        <input type="number" id="length" value="12" min="8" max="30" />

        <br />

        <label for="uppercase">Include Uppercase</label>
        <input type="checkbox" id="uppercase" onclick="enableUClength()" />

        <br />

        <label for="UClength">Uppercase Length</label>
        <input type="number" id="UClength" value="3" min="3" max="10" />

        <br />

        <label for="numbers">Include Numbers:</label>
        <input type="checkbox" id="numbers" checked />

        <br />

        <label for="symbols">Include Symbols</label>
        <input type="checkbox" id="symbols" checked />

        <br />

        <button onclick="generatePassword()">Generate Password</button>
        <br />
        <button onclick="copyToClipboard()">Copy to Clipboard</button>

        <textarea name="" id="password" rows="3" readonly></textarea>

        <div id="success-alert" class="alert alert-success" role="alert" style="display: none;">
            Password generated successfully !
        </div>

    </div>
    <script src="Script1.js"></script>

</body>
</html>

and my JS file:

function generatePassword() {
    const length = document.getElementById('length').value;
    const UClength = document.getElementById('UClength').value;
    const uppercaseCheckbox = document.getElementById('uppercase');
    const numbersCheckbox = document.getElementById('numbers');
    const symbolsCheckbox = document.getElementById('symbols');

    const uppercaseChars = 'QWERTZUIOPASDFGHJKLYXCVBNM';
    const lowercaseChars = 'qwertzuiopasdfghjklyxcvbnm';
    const numberChars = '1234567890';
    const symbolChars = ';~!@#$%^&*_\-+=`|\\(){}\[\]:;"\'<>,.?/';

    let validChars = lowercaseChars;

    if (uppercaseCheckbox.checked) {
        validChars += uppercaseChars;
    }
    if (numbersCheckbox.checked) {
        validChars += numberChars;
    } 
    if (symbolsCheckbox.checked) {
        validChars += symbolChars;
    }

    let password = '';
    password += uppercaseCheckbox.checked ? uppercaseChars.charAt(Math.floor(Math.random() * uppercaseChars.length)) : '';
    password += numbersCheckbox.checked ? numberChars.charAt(Math.floor(Math.random() * numberChars.length)) : '';
    password += symbolsCheckbox.checked ? symbolChars.charAt(Math.floor(Math.random() * symbolChars.length)) : '';

    for (let i = password.length; i < length; i++) {
        const randomIndex = Math.floor(Math.random() * validChars.length);
        password += validChars.charAt(randomIndex);
    }
   
    document.getElementById('password').value = password;
    document.getElementById('success-alert').style.display = 'block';
    setTimeout(() => {
        document.getElementById('success-alert').style.display = 'none';
    }, 3000);

}

What I want to achieve now is to use the value from the UClength input field declared in the HTML file, and have exactly that amount of uppercase characters generated and randomly distribituted within the password string.

What my script is doing so far is that, in case the "Include Uppercase" checkbox is ticked, it generates a random amount of random uppercase characters picked from const uppercaseChars. However I want, if the user let's say enters a 3 into the uppercase length input field, exactly that amount of uppercase characters to be generated and added to password.

If you have an idea for a possible solution I would greatly appreciate your input.


Solution

  • In your code, when uppercase checkbox is checked, you just added uppercaseChars. To add uppercase characters based on input number, I updated the uppercase checkbox checking handler and generated remain passwords.

    This is my updated code.

    function generatePassword() {
        const length = document.getElementById('length').value;
        const UClength = document.getElementById('UClength').value;
        const uppercaseCheckbox = document.getElementById('uppercase');
        const numbersCheckbox = document.getElementById('numbers');
        const symbolsCheckbox = document.getElementById('symbols');
    
        const uppercaseChars = 'QWERTZUIOPASDFGHJKLYXCVBNM';
        const lowercaseChars = 'qwertzuiopasdfghjklyxcvbnm';
        const numberChars = '1234567890';
        const symbolChars = ';~!@#$%^&*_-+=`|\\(){}[]:;"\'<>,.?/';
    
        let validChars = lowercaseChars;
    
        if (numbersCheckbox.checked) {
            validChars += numberChars;
        } 
        if (symbolsCheckbox.checked) {
            validChars += symbolChars;
        }
    
        let password = '';
        let uppercases = '';
    
        // Here, generate uppercase characters based on input number
        if (uppercaseCheckbox.checked) {
            for (let i = 0; i < UClength; i++) {
                uppercases += uppercaseChars.charAt(Math.floor(Math.random() * uppercaseChars.length));
            }
        }
    
        // Here, generate passwords based on remain length except uppercase characters
        let remainingLength = uppercaseCheckbox.checked ? (length - UClength) : length;
    
        for (let i = 0; i < remainingLength; i++) {
            const randomIndex = Math.floor(Math.random() * validChars.length);
            password += validChars.charAt(randomIndex);
        }
    
        password += uppercases;
    
        password = shuffle(password);
    
        document.getElementById('password').value = password;
        document.getElementById('success-alert').style.display = 'block';
        setTimeout(() => {
            document.getElementById('success-alert').style.display = 'none';
        }, 3000);
    }
    
    function shuffle(string) {
        const array = string.split('');
        for (let i = array.length - 1; i > 0; i--) {
            const j = Math.floor(Math.random() * (i + 1));
            [array[i], array[j]] = [array[j], array[i]]; // Swap
        }
        return array.join('');
    }
    <div id="password-generator">
        <h1>Password Generator</h1>
        <label for="length">Password Length</label>
        <input type="number" id="length" value="12" min="8" max="30" />
    
        <br />
    
        <label for="uppercase">Include Uppercase</label>
        <input type="checkbox" id="uppercase" onclick="enableUClength()" />
    
        <br />
    
        <label for="UClength">Uppercase Length</label>
        <input type="number" id="UClength" value="3" min="1" max="10" />
    
        <br />
    
        <label for="numbers">Include Numbers:</label>
        <input type="checkbox" id="numbers" checked />
    
        <br />
    
        <label for="symbols">Include Symbols</label>
        <input type="checkbox" id="symbols" checked />
    
        <br />
    
        <button onclick="generatePassword()">Generate Password</button>
        <br />
        <button onclick="copyToClipboard()">Copy to Clipboard</button>
    
        <textarea name="" id="password" rows="3" readonly></textarea>
    
        <div id="success-alert" class="alert alert-success" role="alert" style="display: none;">
            Password generated successfully!
        </div>
    </div>