I am using the following extension to make sure a string has at least 1 number, 1 letter and between 5-15 characters in length and I feel that it can be more efficient. Any suggestions?
func checkPassword(password : String) -> Bool{
if password.characters.count > 15 || password.characters.count < 5 {
return false
}
let capitalLetterRegEx = ".*[A-Za-z]+.*"
let texttest = NSPredicate(format:"SELF MATCHES %@", capitalLetterRegEx)
let capitalresult = texttest.evaluate(with: password)
let numberRegEx = ".*[0-9]+.*"
let texttest1 = NSPredicate(format:"SELF MATCHES %@", numberRegEx)
let numberresult = texttest1.evaluate(with: password)
let specialRegEx = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLKMNOPQRSTUVWXYZ0123456789"
let texttest2 = NSPredicate(format:"SELF MATCHES %@", specialRegEx)
let specialresult = !texttest2.evaluate(with: password)
if !capitalresult || !numberresult || !specialresult {
return false
}
return true
}
Using Regex
Regex is one approach, but if using it, we may combine your specifications into a single regex search, making use of the positive lookahead assertion technique from the following Q&A:
Here, using the regex:
Where I've include also a negative lookahead assertion (
?!...
) to invalidate the password given any invalid characters.We may implement the regex search as follows:
Using
Set
/CharacterSet
A Swift native approach is using sets of explicitly specified
Character
's:Or, similarly, using the
Foundation
methodrangeOfCharacter(from:)
overCharacterSet
's:If you'd also like to reject passwords that contain any character that is not in the specified sets, you could add a search operation on the (inverted) union of your sets (possibly you also allow some special characters that you'd like to include in this union). E.g., for the
CharacterSet
example:Using pattern matching
Just for the discussion of it, yet another approach is using native Swift pattern matching:
Just note that this approach will allow letters with diacritics (and similar) to pass as the minimum 1 letter specification, e.g.:
as these are contained the the
Character
range"a"..."z"
; see e.g. the excellent answer in the following thread: