Complex password validation using regex - javascript

I am trying to create a javascript regular expression for password validation. The rules for a password to get accepted are
Should contain 12 characters or more
Should contain one of these special characters * ^ !
At least two uppercase characters
At least two numbers
At least one lowercase characters
I found an example online and modified it like following
(?=.*[0-9]{2,})(?=.*[a-z])(?=.*[A-Z]{2,}).{12,}
However this still misses the special character requirement and only works if the upper case characters and numbers are in subsequent order. These are the results I got with this one
aMMericano11 - true
aMmeRican1o1 - false
I wanted the second one to be accepted too with the addition of special characters of course.
Can anyone help me on this?

Disregarding my sarcastic comment about the futility of arbitrary password rules, you are trying to do too much at once.
What you're doing is "does it have 12 letters or more and a symbol from *^! and at least two uppercase letters and at least two numbers and at least one lowercase letter"...
What you should do is:
Does it have 12 letters or more? If not, fail and ask for a longer password
Does it have a symbol? If not, fail and ask for a symbol
Does it have at least two uppercase letters? If not, fail and ask for them.
Does it have at least two numbers? If not, fail and ask for them.
Does it have at least one lowercase letter? If not, fail and ask for it.
Break down big problems into small problems, and you'll end up with better user experience because you can tell your user exactly what you want from them.

The problem is in the lookahead:
(?=.*[0-9]{2,})
This pattern requires that the pattern [0-9]{2,} (e.g., a 2-digit number) appear in the text. What you probably intended was:
(?=(.*[0-9]){2,})
This allows the numbers to be separated by other characters, rather than being consecutive.
The same problem applies to the capital letters rule. Piecing this together, the final expression would be:
(?=(.*[0-9]){2,})(?=.*[\*^!])(?=.*[a-z])(?=(.*[A-Z]){2,}).{12,}
The expression will match if and only if the password meets the validity rules. If more granularity is needed (e.g., to detect that a specific rule is violated), you may need to break the expression into smaller expressions.

Agreed with #Niet the Dark Absol
But still if you want to do this with regEx then break it as:
'ab2c3F*ghijKM'.match(/[\w\W]{12,}/) //Should contain 12 characters or more
'ab2c3F*ghijKM'.match(/[*^!]/) //Should contain one of these special characters * ^ !
'ab2c3F*ghijK'.match(/[A-Z]/g).length>=2 //At least two uppercase characters
'ab2c3F*ghijK'.match(/[\d]/g).length>=2 //At least two numbers characters
'23Fa*K'.match(/[a-z]/) //At least one lowercase characters
Then apply && operations on all these expressions
eg:
var pass = 'ab2cFg*hij3KM';
var isValidInput = pass.match(/[\w\W]{12,}/) && pass.match(/[*^!]/) && (pass.match(/[A-Z]/g).length>=2) && (pass.match(/[\d]/g).length>=2) && pass.match(/[a-z]/)
if(isValidInput) {
console.log('valid')
} else {
console.log('invalid')
}

Related

validate username with regex in javascript

I am a newbie to regex and would like to create a regular expression to check usernames. These are the conditions:
username must have between 4 and 20 characters
username must not contain anything but letters a-z, digits 0-9 and special characters -._
the special characters -._ must not be used successively in order to avoid confusion
the username must not contain whitespaces
Examples
any.user.13 => valid
any..user13 => invalid (two dots successively)
anyuser => valid
any => invalid (too short)
anyuserthathasasupersuperlonglongname => invalid (too many characters)
any username => invalid because of the whitespace
I've tried to create my own regex and only got to the point where I specify the allowed characters:
[a-z0-9.-_]{4,20}
Unfortunately, it still matches a string if there's a whitespace in between and it's possible to have two special chars .-_ successively:
If anybody would be able to provide me with help on this issue, I would be extremely grateful. Please keep in mind that I'm a newbie on regex and still learning it. Therefore, an explanation of your regex would be great.
Thanks in advance :)
Sometimes writing a regular expression can be almost as challenging as finding a user name. But here you were quite close to make it work. I can point out three reasons why your attempt fails.
First of all, we need to match all of the input string, not just a part of it, because we don't want to ignore things like white spaces and other characters that appear in the input. For that, one will typically use the anchors ^ (match start) and $ (match end) respectively.
Another point is that we need to prevent two special characters to appear next to each other. This is best done with a negative lookahead.
Finally, I can see that the tool you are using to test your regex is adding the flags gmi, which is not what we want. Particularly, the i flag says that the regex should be case insensitive, so it should match capital letters like small ones. Remove that flag.
The final regex looks like this:
/^([a-z0-9]|[-._](?![-._])){4,20}$/
There is nothing really cryptic here, except maybe for the group [-._](?![-._]) which means any of -._ not followed by any of -._.

JavaScript password validation regex failing on order of groupings

My password validation criteria is as follows:
Must contain at least two lower case characters
Must contain at least two upper case characters
Must contain at least two numeric characters
Must contain at least two special characters i.e. ##$%
Must be at least 11 characters long
I tried using this for the first four criteria:
/(?:\d{2,})(?:[a-z]{2,})(?:[A-Z]{2,})(?:[!"'#$&()*+-#,.:;<>=?^_`{|}~\/\\]{2,})/g
But it does not match the following string which i would expect it to:
12QAqa##
But it does match:
12qaQA##
The order that the validation criteria is not important. How do i rewrite the regex to not take into account the order?
The following seems to meet all your requirements:
/*
Must contain at least two lower case characters
Must contain at least two upper case characters
Must contain at least two numeric characters
Must contain at least two special characters i.e. ##$%
Must be at least 11 characters long
*/
var password ='12qaQ##123456789A';
var pattern =/^(?=(.*[a-z]){2,})(?=(.*[A-Z]){2,})(?=(.*[0-9]){2,})(?=(.*[!##\$%]){2,}).{11,}$/;
alert( pattern.test(password) );
https://jsfiddle.net/rryg67v1/1/
^ // start of line
(?=(.*[a-z]){2,}) // look ahead and make sure at least two lower case characters exist
(?=(.*[A-Z]){2,}) // look ahead and make sure at least two upper case characters exist
(?=(.*[0-9]){2,}) // look ahead and make sure at least two numbers exist
(?=(.*[!##\$%]){2,}) // look ahead and make sure at least two special characters exist
.{11,} // match at least 11 characters
$ // end of line
Good luck!!

need a regex for password validation that allows all special characters [duplicate]

This question already has an answer here:
Password validation (regex?)
(1 answer)
Closed 8 years ago.
The password requirements are:
at least two letters
at least two numbers
at least one special character (any special character)
at least 8 characters
This one is close but isn't working:
/^(?=.*\d)(?=.*[a-zA-Z])(?=.*[\W]).{8,}$/
What am I doing wrong?
This regex meets your requirements:
/^(?=(?:[^a-z]*[a-z]){2})(?=(?:[^0-9]*[0-9]){2})(?=.*[!-\/:-#\[-`{-~]).{8,}$/i
Play with the demo to see what matches and doesn't match.
Explanation
This is a classic password validation technique with lookarounds as explained in this article
The i flag at the end makes it case-insensitive so we don't have to say a-zA-Z
The ^ anchor asserts that we are at the beginning of the string
The first lookahead (?=(?:[^a-z]*[a-z]){2}) asserts that what follows at this position (the beginning of the string) is any characters that are not a letter, followed by one letter... twice, ensuring there are at least two letters
The second lookahead (?=(?:[^0-9]*[0-9]){2}) asserts that what follows at this position (still the beginning of the string) is any characters that are not a digit, followed by one digit... twice, ensuring there are at least two letters
The third lookahead (?=.*[!-\/:-#\[-{-~])` asserts that what follows at this position (still the beginning of the string) is any characters, followed by one special character
The $ anchor asserts that we are at the end of the string
Note about special characters
The regex [!-\/:-#\[-{-~]` specifically picks out all printable chars that are neither digits nor letters from the ASCII table. If this includes chars you don't want, make it more restrictive.
A regex is probably inappropriate for this; it's hard to glance at the regex you've got and immediately have any idea what the requirements are, let alone how to modify them. You might want to just count the number of characters in each group directly, then check that those counts all pass the appropriate threshold.
That said: consider that this would enforce really awkward passwords, yet disallow xkcd-style passwords. I strongly encourage you to take a more heuristic approach, where a longer password loosens the other restrictions. There are other considerations to enforcing a strong password, too, like similarity to dictionary words and number of unique characters.
Honestly you might be best off just requiring passphrases :)
I'd say:
/^(?=.*\d.*\d)(?=.*[a-zA-Z].*[a-zA-Z])(?=.*[\W]).{8,}$/
Your regex was missing the 2 digits and 2 letters requirements.
How about:
/^(?=.{2,}\d)(?=.{2,}[a-zA-Z])(?=.*[\W]).{8,}$/
It should meet your requirement.
Depends on what you consider to be a "special character". If a special character is anything that is not a digit or a letter, and if Spaces are not allowed in the password, then:
^(?=(?:\S*\d){2})(?=(?:\S*[A-Za-z]){2})(?=\S*[^A-Za-z0-9])\S{8,}
or, with the "escapes":
"^(?=(?:\\S*\\d){2})(?=(?:\\S*[A-Za-z]){2})(?=\\S*[^A-Za-z0-9])\\S{8,}"
If you choose to allow spaces, replace \S with a dot .
If you want to define "special characters" as only including certain characters, or as excluding other characters in addition to letters and digits, edit the character class in the final lookahead.

UK bank sort code javascript regular expression

I'm trying to create a regular expression in javascript for a UK bank sort code so that the user can input 6 digits, or 6 digits with a hyphen between pairs. For example "123456" or "12-34-56". Also not all of the digits can be 0.
So far I've got /(?!0{2}(-?0{2}){2})(\d{2}(-\d{2}){2})|(\d{6})/ and this jsFiddle to test.
This is my first regular expression so I'm not sure I'm doing it right. The test for 6 0-digits should fail and I thought the -? optional hyphen in the lookahead would cause it to treat it the same as 6 0-digits with hyphens, but it isn't.
I'd appreciate some help and any criticism if I'm doing it completely incorrectly!
Just to answer your question, you can validate user input with:
/^(?!(?:0{6}|00-00-00))(?:\d{6}|\d\d-\d\d-\d\d)$/.test(inputString)
It will strictly match only input in the form XX-XX-XX or XXXXXX where X are digits, and will exclude 00-00-00, 000000 along with any other cases (e.g. XX-XXXX or XXXX-XX).
However, in my opinion, as stated in other comments, I think it is still better if you force user to either always enter the hyphen, or none at all. Being extra strict when dealing with anything related to money saves (unknown) troubles later.
Since any of the digits can be zero, but not all at once, you should treat the one case where they are all zero as a single, special case.
You are checking for two digits (\d{2}), then an optional hyphen (-?), then another two digits (\d{2}) and another optional hyphen (-?), before another two digits (\d{2}).
Putting this together gives \d{2}-?\d{2}-?\d{2}, but you can simplify this further:
(\d{2}-?){2}\d{2}
You then use the following pseudocode to match the format but not 000000 or 00-00-00:
if (string.match("/(\d{2}-?){2}\d{2}/") && !string.match("/(00-?){2}00/"))
//then it's a valid code, you could also use (0{2}-?){2}0{2} to check zeros
You may wish to add the string anchors ^ (start) and $ (end) to check the entire string.

Need help: RegEx for a password containing numbers and special chars

I need help with a RegEx for a password. The password must contain at least one special char (like "§$&/!) AND a number.
E.g. a password like "EdfA433&" must be valid whereas "aASEas§ö" not as it contains not a number.
I have the following RegEx so far:
^(?=.*[0-9])(?=.*[a-zA-Z]).{3,}$
But this one is obviously checking only for a number. Can anyone help?
You're better off just using multiple more simple regular expressions: any code checking anything like this won't be performance sensitive, and the additional complexity of maintenance given a more complex regexp probably isn't justifiable.
So, what I'd go for:
var valid = foo.match(/[0-9]/) && foo.match(/["§$&/!]/);
I wonder if you really want to define special characters like that: Does é count as a special character? Does ~ count as a special character?
^(?=.*\d)(?=.*\W).{3,}$
checks for at least one digit (\d) and one non-alphanumeric character (\W). \W is the inverse of \w which matches digits, letters and the underscore.
If you want to include the underscore in the list of "special characters", use
^(?=.*\d)(?=.*[\W_]).{3,}$
I would divide function that checks if password is "hard" into some parts and in each part I would check one condition. You can see some complicated regex on Daily WTF with password reset: http://thedailywtf.com/Articles/The-Password-Reset-Facade.aspx

Categories