Strong passwords validation laravel [duplicate] - php

This question already has answers here:
Regex for password must contain at least eight characters, at least one number and both lower and uppercase letters and special characters
(42 answers)
Closed 2 years ago.
So before any one shuts this down, I am referencing an answer and asking a question here.
So the question I have is I want a strong password validation for laravel, something that includes 10 character, numbers, upper lower case, so on and so forth.
I found it: https://stackoverflow.com/a/31549892/1270259
The problem is, this regex looks off:
/^.*(?=.{3,})(?=.*[a-zA-Z])(?=.*[0-9])(?=.*[\d\X])(?=.*[!$#%]).*$/
And since I am not good with regex I thought I would ask how can I fix it such that it validates:
Must be 10 characters long
Must contain upper and lower case
Must contain at least one number
Must contain at least one special character.
I feel like they were close in the answer. When this is run against github actions the error that comes back is preg_match(): Compilation failed: escape sequence is invalid in character class at offset 46.
Any thoughts as too how I can make this work for Laravel 7 to match the above constraints?

Use the principle of contrast:
^
(?=[^a-z]*[a-z]) # ensure one lower case letter
(?=[^A-Z]*[A-Z]) # ensure one upper case letter
(?=\D*\d) # ensure a digit
(?=[^!#?]*[!#?]) # special chars
.{10,} # at least 10 characters long
$
You can extend the special char section, of course.
See a demo on regex101.com.

Related

Regular expression - avoid the repetition of the sequence of the same letters

I'm trying to make a check on the password inserted by a user, working on a PHP website.
My check wants to:
at least 8 characters
maximum 20 characters
accept letters, numbers, and common special characters like (dot) # + $ - _ !
Until this point I've been able to figure out the right expression, but now I want to add an other rule, where an user can't write the same sequence of letter more then 1 time.
Let's say that, not considering the repetition of two times of the same letter, if the user write the same string (equal or more than 3 characters) more then once, it should not match.
For example:
abcde not valid - should be at least 8 characters
abcde1234 valid
abcd1abcd1 not valid due to repetition of the string abcd1
More examples (updated):
abababab not valid - the string "ab" is repited 2 times or more
aaaaaaaa not valid - the string aaa is repited more then once
helloworld valid - even if there is the letter "l" repeated two times
Any suggestion?
I don't know is it's possibile to write down a correct RegExp, maybe I'm trying to do something impossibile.
Before leaving the idea, I was curious to check the opinion of someone who know more then me in RegExp.
Thanks in advance
^(?!.*?(.+)\1)([\w#+$!.-]+){8,20}$
seems to work well: http://regex101.com/r/cU9lD0/1
The tricky part is ^(?!.*?(.+)\1) which reads "start of input, when not followed by: something, then some substring, then that substring once again".
That being said, all "password validation" is a quite pointless enterprise, which actually stops people from using really good passwords.

Building an algorithm to find special chars in words and replace them [duplicate]

This question already has answers here:
PHP character encoding problems
(8 answers)
Closed 8 years ago.
I will start by saing that i have NO INFLUENCE on the input and suggestions to correct it cant help me.
I am asking how to fix the output.
I have descriptions in German. The problem is that some of them were corrupted in the process. Words that have one of 7 German special letters, can have corrupted chars like:
('%�%')
('%¿%')
('%Ø%')
('%¶%')
('%Â%')
('%Ã%')
('%©%')
The difficulty is also because one letter can be "translated" to one corrupted char or even 3 corrupted chars. So the word "für" can be corrupted to "fÂr" or to "f??r" or to "f�r" and i dont have any specific pattern that i can use in regex.
I need to build some algorithm that:
Finds a corruption in a given description.
Finds the correction for the corrupted word.
What do i have?
The description
A German dictionary with all the words that have special chars.
I want to implement it in PHP\Queries but its not mandatory. Any ideas how to do it?
A general algorithm (you'll have to implement it in your programming language) goes like this:
First, let's write our helper function:
1) Given a word, look for each corrupted char in the word.
2) starting with the first, make a switch between a corrupted char and a special german char.
3) see if there are any words (look in the "dictionary") that start with the sub-string of up to the char you just switched. If none, go back to 2 and make a different switch. If there are, keep switching the next cirrupted chars.
4) when you can't switch any more corrupted chars, check if this is a word. If it is, add it to the set if possible words. Else, go back and make a different switch.
Then, let's go to the main algorithm:
1) search for a corrupted char (one of those you stated), this can be done by simply checking all the chars one by one.
2) When you find a corrupted char - send the entire word the char belongs to to the helper function.
3) choose among the options suggested by the helper function, or just let the helper function choose by itself.
4) make the switch, move to the end if the string.
5) return to 1
Sorry for any typos, hope it helpes!

Handling danish special characters [duplicate]

This question already has answers here:
how to replace special characters with the ones they're based on in PHP?
(8 answers)
Closed 8 years ago.
I am trying to parse a string, split it on what is not a letter or number
$parse_query_arguments = preg_split("/[^a-z0-9]+/i", 'København');
and construct a mysql query.
Even if I skip the preg_split and try to enter the string directly it breaks it into 2 different strings, 'K' and 'benhavn'.
How can I deal with these issues?
If you're using literal characters like a-z then it won't match accented ones. You might want to use the various character classes available to do more generic matching:
/[[:alpha:][:digit]]/
The [:alpha:] set is much broader in scope than a-z. Remember character matching is done based on character code, and a-z in order take, literally, characters between a and z by index. Characters like ø lie outside this range even if they'd fall between that alphabetically.
Computers work in ASCII-abetical (UNICODEical?) order.
This might help explain what is going on in your regex... Regex and Unicode.
You could try something like \p{L} as explained in this question

Password Strength Pattern

Should I use a password pattern like a-zA-Z0-9 and also require at least one of each character class in the password, or simply allow anything inside the password?
What do sites allow the user to use as his/her password? Is there anything else I should consider?
a-ZA-Z0-9 is overly limited. You should let me use any characters, and enforce minimum requirements (i.e. at least 8 characters, at least one letter and one number)
Password Entropy
The test of a good password is not the number of sets of characters represented but Entropy.
Testing for Entropy: The people at Dropbox have put together this fantastic tool called zxcvbn to do just that. I would highly recommend reading their write-up explaining it here.
Brief Explanation: Both character classes (lower case, upper case, digits and special characters) and length are both important because together they raise password entropy (length does this much faster than character classes though) but users then tend toward predictable patterns which lowers entropy.
This may be humour but it helpfully illustrates part of the point:
http://xkcd.com/936/
There should be no limit to what the user should be able to use. Since you would hash the password before you store it anyways (i hope) this will make no difference what the password contain.
If you set requirements, they should be minimum requirements.
Password Regular Expression Pattern
((?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[##$%]).{6,20})
Breakdown
( # Start of group
(?=.*\d) # must contains one digit from 0-9
(?=.*[a-z]) # must contains one lowercase characters
(?=.*[A-Z]) # must contains one uppercase characters
(?=.*[##$%]) # must contains one special symbols in the list "##$%"
. # match anything with previous condition checking
{6,20} # length at least 6 characters and maximum of 20
) # End of group
Related:
Regular Expression for Password
minimum 8 characters, preferable 12
at least one digit, at least one lower case, at least one upper case, at least one symbol (*/%...)

Help with password complexity regex

I'm using the following regex to validate password complexity:
/^.*(?=.{6,12})(?=.*[0-9]{2})(?=.*[A-Z]{2})(?=.*[a-z]{2}).*$/
In a nutshell: 2 lowercase, 2 uppercase, 2 numbers, min length is 6 and max length is 12.
It works perfectly, except for the maximum length, when I'm using a minimum length as well.
For example:
/^.*(?=.{6,})(?=.*[0-9]{2})(?=.*[A-Z]{2})(?=.*[a-z]{2}).*$/
This correctly requires a minimum length of 6!
And this:
/^.*(?=.{,12})(?=.*[0-9]{2})(?=.*[A-Z]{2})(?=.*[a-z]{2}).*$/
Correctly requires a maximum length of 12.
However, when I pair them together as in the first example, it just doesn't work!!
What gives? Thanks!
You want:
/^(?=.{6,12}$)...
What you're doing is saying: find me any sequence of characters that is followed by:
6-12 characters
another sequence of characters that is followed by 2 digits
another sequence of characters that is followed by 2 uppercase letters
another sequence of characters that is followed by 2 lowercase letters
And all that is followed by yet another sequence of characters. That's why the maximum length isn't working because 30 characters followed by 00AAaa and another 30 characters will pass.
Also what you're doing is forcing two numbers together. To be less stringent than that but requiring at least two numbers anywhere in the string:
/^(?=.{6,12}$)(?=(.*?\d){2})(?=(.*?[A-Z]){2})(?=(.*?[a-z]){2})/
Lastly you'll note that I'm using non-greedy expressions (.*?). That will avoid a lot of backtracking and for this kind of validation is what you should generally use. The difference between:
(.*\d){2}
and
(.*?\d){2}
Is that the first will grab all the characters with .* and then look for a digit. It won't find one because it will be at the end of the string so it will backtrack one characters and then look for a digit. If it's not a digit it will keep backtracking until it finds one. After it does it will match that whole expression a second time, which will trigger even more backtracking.
That's what greedy wildcards means.
The second version will pass on zero characters to .*? and look for a digit. If it's not a digit .*? will grab another characters and then look for a digit and so on. Particularly on long search strings this can be orders of magnitude faster. On a short password it almost certainly won't make a difference but it's a good habit to get into of knowing how the regex matcher works and writing the best regex you can.
That being said, this is probably an example of being too clever for your own good. If a password is rejected as not satisfying those conditions, how do you determine which one failed in order to give feedback to the user about what to fix? A programmatic solution is, in practice, probably preferable.

Categories