Is my password secure?

-1

0

Task:

Take a string as input and if it meets the requirements, accept the password.

Input: a string, e.g. someString, asjk23t89h, 123456789abcdef.

Output: two distinct values representing "secure" and "insecure", e.g. 0/1, true/false, secure/insecure.

Password requirements:

In order for a password to be determined as secure, it must:

  • Be at least 8 characters in length.
  • Contain at least one character each from the four groups a-z, A-Z, 0-9 and !"£$%^&*()_+-={}[]:@~;'#<>?,./

Examples:

  • password -> insecure
  • password123 -> insecure
  • L0h~[/1s7C -> secure
  • h&fn3*# -> insecure
  • C#de g07F -> secure

Winning:

This is code golf, the shortest answer wins.

Joe

Posted 2017-10-16T09:24:05.103

Reputation: 117

3Related. – Laikoni – 2017-10-16T10:52:16.827

Can you clarify the "ASCII symbol" part? Do you mean any non-letter, non-digit ASCII character (including spaces, linefeeds, and other control characters)? Or do you mean printable/non-whitespace ASCII only? Also what range of characters can appear in the input in the first place? – Martin Ender – 2017-10-16T12:34:38.283

2Did you add a non-ASCII character (£) to the list intentionally? – Martin Ender – 2017-10-16T12:39:27.820

"Is my password secure?" s->"no" (7 bytes answer in Java \o/) – Olivier Grégoire – 2017-10-16T14:36:35.847

Answers

3

Java 8, 93 62 65 60 bytes

s->s.matches("([a-z]()|[A-Z]()|\\d()|.()){8,}+\\2\\3\\4\\5")

+3 bytes due to a bugfix, pointed out by @MartinEnder♦.
-5 bytes thanks to @jaytea by using capture groups instead of lookaheads, since the matches are not overlapping.

Old answer with (redundant) dictionary (93 96 bytes):

d->s->!d.contains(s.toLowerCase())&s.matches("(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[\\W_]).{8,}")

Because I can't think of a single word in the dictionary that contains at least one uppercase, lowercase, digit and other ASCII character.. So the dictionary-check is kinda redundant in that case.

Explanation:

Try it here.

s->                    // Method with String parameter and boolean return-type
  s.matches("([a-z]()  //  Checks if the String contains at least one lowercase letter
             |[A-Z]()  //  and at least one uppercase letter
             |\\d()    //  and at least one digit
             .()       //  and at least one other ASCII character
             ){8,}+\\2\\3\\4\\5")
                       //  And has a length of at least 8
                       // End of method (implicit / single-line return-statement)

Kevin Cruijssen

Posted 2017-10-16T09:24:05.103

Reputation: 67 575

1

Here is a trick for golfing multiple, non-overlapping subexpressions that's shorter than using lookaheads: "(a-z|A-Z|\d()|.()){8,}+\2\3\4\5"

– jaytea – 2017-10-16T14:30:55.360

2

Python 2, 112 107 83 86 bytes

lambda s:re.match(r'(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[\W_]).{8,}',s)!=None
import re

Try it online!

TFeld

Posted 2017-10-16T09:24:05.103

Reputation: 19 246

2You can remove the !=None as the match will either return a truthy or falsey value (a match object or None) – caird coinheringaahing – 2017-10-16T15:18:39.010