-1
\$\begingroup\$

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.

\$\endgroup\$
  • 3
    \$\begingroup\$ Related. \$\endgroup\$ – Laikoni Oct 16 '17 at 10:52
  • \$\begingroup\$ 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? \$\endgroup\$ – Martin Ender Oct 16 '17 at 12:34
  • 2
    \$\begingroup\$ Did you add a non-ASCII character (£) to the list intentionally? \$\endgroup\$ – Martin Ender Oct 16 '17 at 12:39
  • \$\begingroup\$ "Is my password secure?" s->"no" (7 bytes answer in Java \o/) \$\endgroup\$ – Olivier Grégoire Oct 16 '17 at 14:36
3
\$\begingroup\$

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)
\$\endgroup\$
  • 1
    \$\begingroup\$ 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" \$\endgroup\$ – jaytea Oct 16 '17 at 14:30
2
\$\begingroup\$

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!

\$\endgroup\$
  • 2
    \$\begingroup\$ You can remove the !=None as the match will either return a truthy or falsey value (a match object or None) \$\endgroup\$ – caird coinheringaahing Oct 16 '17 at 15:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.