Проверка пароля в UITextField в iOS
У меня есть 1 UITextfield
для пароля в приложении iPhone.
Я хочу проверить это текстовое поле со следующей валидацией.
- Должно быть не менее 10 символов
- Должен содержать хотя бы одну строчную букву, одну букву верхнего регистра, одну цифру и один специальный символ
- Допустимые специальные символы:
@#$%^&+=^.*(?=.{10,})(?=.*d)(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=]).*$
Как я могу ограничить UITextfield
вышеуказанными требованиями?
Ответы
Ответ 1
Вот как я это сделаю. Проверка должна выполняться в конце, когда пользователь набрал пароль, а не между ними. Я не буду использовать NSRegularExpression
.
-(void)textFieldDidEndEditing:(UITextField *)textField{
int numberofCharacters = 0;
BOOL lowerCaseLetter,upperCaseLetter,digit,specialCharacter = 0;
if([textField.text length] >= 10)
{
for (int i = 0; i < [textfield.text length]; i++)
{
unichar c = [textfield.text characterAtIndex:i];
if(!lowerCaseLetter)
{
lowerCaseLetter = [[NSCharacterSet lowercaseLetterCharacterSet] characterIsMember:c];
}
if(!upperCaseLetter)
{
upperCaseLetter = [[NSCharacterSet uppercaseLetterCharacterSet] characterIsMember:c];
}
if(!digit)
{
digit = [[NSCharacterSet decimalDigitCharacterSet] characterIsMember:c];
}
if(!specialCharacter)
{
specialCharacter = [[NSCharacterSet symbolCharacterSet] characterIsMember:c];
}
}
if(specialCharacter && digit && lowerCaseLetter && upperCaseLetter)
{
//do what u want
}
else
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error"
message:@"Please Ensure that you have at least one lower case letter, one upper case letter, one digit and one special character"
delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alert show];
}
}
else
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error"
message:@"Please Enter at least 10 password"
delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alert show];
}
}
Надеюсь, что это поможет...
Ответ 2
Вы также можете сделать это, используя Regex
. Вот несколько примеров, которые я вам предоставляю:
// *** Validation for Password ***
// "^(?=.*[A-Za-z])(?=.*\\d)[A-Za-z\\d]{8,}$" --> (Minimum 8 characters at least 1 Alphabet and 1 Number)
// "^(?=.*[A-Za-z])(?=.*\\d)(?=.*[[email protected]$!%*#?&])[A-Za-z\\[email protected]$!%*#?&]{8,16}$" --> (Minimum 8 and Maximum 16 characters at least 1 Alphabet, 1 Number and 1 Special Character)
// "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)[a-zA-Z\\d]{8,}$" --> (Minimum 8 characters at least 1 Uppercase Alphabet, 1 Lowercase Alphabet and 1 Number)
// "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[[email protected]$!%*?&])[A-Za-z\\[email protected]$!%*?&]{8,}" --> (Minimum 8 characters at least 1 Uppercase Alphabet, 1 Lowercase Alphabet, 1 Number and 1 Special Character)
// "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[[email protected]$!%*?&])[A-Za-z\\[email protected]$!%*?&]{8,10}" --> (Minimum 8 and Maximum 10 characters at least 1 Uppercase Alphabet, 1 Lowercase Alphabet, 1 Number and 1 Special Character)
Четвертый из списка - ваш случай, следующий фрагмент кода показывает, как его использовать:
-(BOOL)isValidPassword:(NSString *)passwordString
{
NSString *stricterFilterString = @"^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[[email protected]$!%*?&])[A-Za-z\\[email protected]$!%*?&]{10,}";
NSPredicate *passwordTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", stricterFilterString];
return [passwordTest evaluateWithObject:passwordString];
}
Используя метод:
if(![self isValidPassword:txtPassword.text]) {
/* Show alert: "Password must be minimum 10 characters,
at least 1 Uppercase Alphabet, 1 Lowercase Alphabet,
1 Number and 1 Special Character" */
}
else {
// Password is valid
}
Ответ 3
Условие: пароль должен содержать как минимум 8 символов, 1 верхний регистр и 1 номер
Решение в Swift 3
вы можете написать Расширение строки, как это,
extension String {
func isValidPassword() -> Bool {
let regularExpression = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[[email protected]$!%*?&])[A-Za-z\\[email protected]$!%*?&]{8,}"
let passwordValidation = NSPredicate.init(format: "SELF MATCHES %@", regularExpression)
return passwordValidation.evaluate(with: self)
}
}
//Example 1
var password = "@Abcdef011" //string from UITextField (Password)
password.isValidPassword() // -> true
//Example 2
var password = "Abcdef011" //string from UITextField
password.isValidPassword() // -> false
или вы можете написать такую функцию,
func validate(password: String) -> Bool
{
let regularExpression = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[[email protected]$!%*?&])[A-Za-z\\[email protected]$!%*?&]{8,}"
let passwordValidation = NSPredicate.init(format: "SELF MATCHES %@", regularExpression)
return passwordValidation.evaluate(with: password)
}
это даст вам тот же результат.
Ответ 4
Вы можете проверить свою проверку пароля, используя приведенную ниже функцию, просто передайте строку пароля, и это вернет вам значение BOOL.
-(BOOL) isPasswordValid:(NSString *)pwd {
NSCharacterSet *upperCaseChars = [NSCharacterSet characterSetWithCharactersInString:@"ABCDEFGHIJKLKMNOPQRSTUVWXYZ"];
NSCharacterSet *lowerCaseChars = [NSCharacterSet characterSetWithCharactersInString:@"abcdefghijklmnopqrstuvwxyz"];
//NSCharacterSet *numbers = [NSCharacterSet characterSetWithCharactersInString:@"0123456789"];
if ( [pwd length]<6 || [pwd length]>20 )
return NO; // too long or too short
NSRange rang;
rang = [pwd rangeOfCharacterFromSet:[NSCharacterSet letterCharacterSet]];
if ( !rang.length )
return NO; // no letter
rang = [pwd rangeOfCharacterFromSet:[NSCharacterSet decimalDigitCharacterSet]];
if ( !rang.length )
return NO; // no number;
rang = [pwd rangeOfCharacterFromSet:upperCaseChars];
if ( !rang.length )
return NO; // no uppercase letter;
rang = [pwd rangeOfCharacterFromSet:lowerCaseChars];
if ( !rang.length )
return NO; // no lowerCase Chars;
return YES;
}
Ответ 5
используйте регулярное выражение (класс NSRegularExpression имеет документы о том, как писать сам patten), а затем:
- (BOOL)textField:(UITextField *)theTextField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
//delete
if (string.length == 0) {
return YES;
}
if (self.regEx) {
NSMutableString* check = [NSMutableString stringWithString:theTextField.text];
[check replaceCharactersInRange:range withString:string];
NSTextCheckingResult* match = [self.regEx firstMatchInString:check options:0 range:NSMakeRange(0, [check length])];
if (match.range.length != check.length) {
return NO;
}
}
}
Предупреждение. Ограничение ввода таким образом действительно запутывает пользователей. Вы вводите и печатаете, и вводимый вами символ просто не отображается!
Возможно, я поеду с небольшим красным (!) рядом с тестовым полем, но я всегда разрешу сам ввод!
Ответ 6
У меня есть это элегантное решение для форм (например, регистрация), где у вас много валидации
В моем пользовательском UITextField есть выход:
@IBInspectable var regexpValidation: String? = nil
В раскадровке я могу получить доступ к нему через инспектор атрибутов и поместить строку регулярного выражения как это (для электронной почты):
[a-z0-9!#$%&'*+/=?^_
{|} ~ -] + (?.!? [А-z0-9 # $% & '* +/= ^ _ {|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?
то в моем подклассе у меня есть этот вычисленный var:
@IBInspectable var regexpValidation: String? = nil//Необязательно, установите это в InterfaceBuilder
var inputIsValid: Bool {
get {
if let expr = regexpValidation {
return (text.rangeOfString(expr, options: NSStringCompareOptions.RegularExpressionSearch, range: nil, locale: nil) != nil)
} else {
return true
}
}
}
который можно использовать следующим образом:
override func resignFirstResponder() -> Bool {
if (inputIsValid) {
return super.resignFirstResponder()
}
else {
text = ""
return false
}
}
Ответ 7
Вам нужно написать свой код проверки в этом методе делегата UITextField
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
Несколько ссылок, которые вы можете захотеть ссылаться на реализацию
как использовать регулярное выражение в iOS sdk
iOS TextField Validation
Ответ 8
Использовать метод control:isValidObject:
протокола NSTextFieldDelegate
, который позволяет проверить значение NSTextField. Предполагая, что вы правильно настроили все ваши биты и части компоновщика интерфейса, вы можете сделать что-то вроде этого:
@interface PreferencesController : NSWindowController <NSTextFieldDelegate> {
IBOutlet NSTextField *username, *password;
}
@end
@implementation PreferencesController
- (BOOL)control:(NSControl *)control isValidObject:(id)object
{
if (control == password) {
// Perform validation and return YES or NO
}
return YES;
}
@end
Ответ 9
для меня Лучшим способом было использовать NSPredicate
и regex.
это регулярное выражение для вашего случая: ^(?=.{10,})(?=.*[0-9])(?=.*[a-zA-Z])([@#$%^&=a-zA-Z0-9_-]+)$
![образ, созданный на debuggex.com]()
объективный код C:
NSString *regex = @"^(?=.{10,})(?=.*[0-9])(?=.*[a-zA-Z])([@#$%^&=a-zA-Z0-9_-]+)$";
NSPredicate *passwordTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
BOOL isValid = [passwordTest evaluateWithObject:yourTextfield.text];
Ответ 10
Swift 3
проверить, является ли пароль сильным?
- длина больше или равна 8
- строчными
- прописные
- десятичные цифры
-
специальные символы, такие как! @# $% ^ & *() _- + необязательно
Почему я не использую регулярное выражение?
Потому что сложно поддерживать зарезервированные символы в обычных
синтаксис выражений.
func isValidated(_ password: String) -> Bool {
var lowerCaseLetter: Bool = false
var upperCaseLetter: Bool = false
var digit: Bool = false
var specialCharacter: Bool = false
if password.characters.count >= 8 {
for char in password.unicodeScalars {
if !lowerCaseLetter {
lowerCaseLetter = CharacterSet.lowercaseLetters.contains(char)
}
if !upperCaseLetter {
upperCaseLetter = CharacterSet.uppercaseLetters.contains(char)
}
if !digit {
digit = CharacterSet.decimalDigits.contains(char)
}
if !specialCharacter {
specialCharacter = CharacterSet.punctuationCharacters.contains(char)
}
}
if specialCharacter || (digit && lowerCaseLetter && upperCaseLetter) {
//do what u want
return true
}
else {
return false
}
}
return false
}
let isVaildPass:Bool = isValidated("Test**00+-")
print(isVaildPass)