0

I am trying to write a javascript validation for a password with the following criteria:

Password Must:

  • Have exactly 8 characters
  • Contain letters and numbers
  • Contain at least two numbers

EG: "helloo15", "1helloo5" and "h1111111" are valid, "helloo1500", "27272727"and "helloos5" are invalid.

This is what I currently have:

//Password
    var pw = document.myForm.password1.value;
    var Vpw = /^[a-zA-Z0-9]{8}$/;
    if (!Vpw.test(pw)) {
        alert("Password must be 8 digits long. It must include a maximum of two numbers.");
        return false;           
    } else {
/*      alert("Valid CCV!");     */     
    }

But I can't figure out how to limit it to a minimum of 2 numbers anywhere in the string. Thanks!

bandoy123
  • 253
  • 4
  • 12
  • Your error message doesn't seem to reflect what you explained... > EG: "helloo15", "1helloo5" and "h1111111" are valid, "helloo1500", "27272727"and "helloos5" are invalid. ... "h1111111" has more than 2 numbers – kennasoft Sep 12 '15 at 01:23
  • Just change your regex for `/^(?=.*\d){2,}(?=.*[a-zA-Z]).{8}$/` – Aguardientico Sep 12 '15 at 01:27

3 Answers3

3

try this one

    var pass = "some44Passddword";     //document.myForm.password1.value;
    var patt = new RegExp("^(?=(.*[a-zA-Z]){1,})(?=(.*[0-9]){2,}).{8}$");

    if ( !patt.test(pass) ) 
    {
        alert("Password must be 8 digits long. It must include a maximum of two numbers.");
        //return false;           
    } 
    else 
    {
        alert("Valid!");
    }

you can check this here: https://jsfiddle.net/esj9go59/


UPDATE

for also avoiding non-word characters like "$%#^&" you should use

    ^(?!(.*[^a-zA-Z0-9]){1,})(?=(.*[a-zA-Z]){1,})(?=(.*[0-9]){2,}).{8}$

regular expression.

Please notice that for some reason javascript test function does not respect \W as non-word characters and it is better to use [^a-zA-Z0-9] instead of this as stated in comment below

m.antkowicz
  • 13,268
  • 18
  • 37
1

I know everyone has come through here and told you to use regular expressions (partly because you started with that). Please don't. There are times in which regular expressions are the better choice. That is rare though, they are way overused, and this is not one of those times. The following code is way more readable than the regex mess in the accepted answer.

This code also allows you to test each condition individually and give customized errors to the user.

function isValidPassword(str)
{
    return str.length == 8 && 
        digitCount(str) >= 2 && 
        hasLetters(str) && 
        hasOnlyLettersAndDigits(str);
}

function isAsciiCodeLetter(asciiCode)
{
    return (65 <= asciiCode && asciiCode <= 90) ||
        (97 <= asciiCode && asciiCode <= 122);
}

function isAsciiCodeDigit(asciiCode)
{
    return 48 <= asciiCode && asciiCode <= 57;
}

function hasLetters(str)
{
    for (var i = 0, len = str.length; i < len; i++) 
    {
        if (isAsciiCodeLetter(str.charCodeAt(i)))
            return true;
    }
    return false;
}

function hasOnlyLettersAndDigits(str)
{
    for (var i = 0, len = str.length; i < len; i++) 
    {
        var asciiCode = str.charCodeAt(i);
        if (!isAsciiCodeLetter(str.charCodeAt(i)) &&
            !isAsciiCodeDigit(str.charCodeAt(i)))
        {
            return false;
        }
    }
    return true;
}

function digitCount(str)
{
    var count = 0;
    for (var i = 0, len = str.length; i < len; i++) 
    {
        if (isAsciiCodeDigit(str.charCodeAt(i)))
        {
            count++;
        }
    }
    return count;
}

Don't use regex, but if you're dead set on using regex, match on [0-9].*[0-9] for 2 digits, [a-zA-Z] for a character, and ^[0-9a-zA-Z]{8}$ for the length and characters/digits only requirement. That's at least sort of readable:

function isValidPassword(str)
{
    var atLeastTwoDigits = new RegExp("[0-9].*[0-9]");
    var atLeastOneCharacter = new RegExp("[a-zA-Z]");
    var onlyEightCharactersAndDigits = new RegExp("^[0-9a-zA-Z]{8}$");

    return atLeastTwoDigits.test(str) && 
        atLeastOneCharacter.test(str) &&
        onlyEightCharactersAndDigits.test(str);
}

Test cases:

alert(isValidPassword("asdfasdf")); //false
alert(isValidPassword("asdfasd4")); //false
alert(isValidPassword("7sdfasd4")); //true
alert(isValidPassword("asdfas`f")); //false
alert(isValidPassword("asd3a4df-")); //false
alert(isValidPassword("asd3a4f-")); //false
alert(isValidPassword("asd3a4df")); //true
alert(isValidPassword("12345678")); //false
alert(isValidPassword("1helloo5")); //true
alert(isValidPassword("helloos5")); //false
alert(isValidPassword("45345345")); //false
alert(isValidPassword("123`567d")); //false
Millie Smith
  • 4,536
  • 2
  • 24
  • 60
0

You can use another regex for that:

//This will yield FALSE (as you expect)
var pw = "1jkj3kjlkj3"

alert(pw.replace(/[^0-9]/g,"").length >= 2)

You can create a function or add that into your if.

Cacho Santa
  • 6,846
  • 6
  • 41
  • 73