Cómo verificar si la cadena tiene una letra minúscula, una letra mayúscula y un número

Necesito hacer un verificador de contraseña simple, debe verificar si la cadena tiene al menos una letra minúscula, una letra mayúscula y un número.

esto es lo que tengo

passwd = raw_input("enter your password: ") upper = 0 lower = 0 number = 0 while len(passwd) < 7 and upper <= 0 and lower <= 0 and number <= 0: print 'start' for x in passwd: if x.isupper()==True: print 'upper' upper+=1 elif x.islower()==True: print 'lower' lower+=1 elif x.isalpha()==False: print 'num' number+=1 print ('password not complex enough') upper = 0 lower = 0 number = 0 passwd = raw_input('please enter password again ') 

Esas impresiones de apariencia aleatoria son para depuración, por lo que puedo ver dónde está llegando.

y lo que parece que está sucediendo es que solo comprueba la primera condición, la condición de longitud y luego abandona el bucle.

Aquí hay una muestra de lo que está sucediendo.

 enter your password: pA1 start lower upper num password not complex enough please enter password again password 

¿Por qué solo se verifica la condición de longitud? ¿qué hice mal?

Tienes algunos problemas con tu lógica de comprobación. En primer lugar, restablece las variables de control antes de que la condición while pueda verificarlas. Además, utilizó and para probar si todas las condiciones son verdaderas, mientras que or es lo que debería estar usando. Si desea mantener la estructura básica de su código, la mejor manera de hacerlo es usar solo True en su sentencia while y luego break el ciclo una vez que se cumplan todas las condiciones. Por supuesto, como se muestra en las otras respuestas, hay formas mucho más compactas de verificar que se cumplan todas las condiciones.

 passwd = raw_input("enter your password: ") upper = 0 lower = 0 number = 0 while True: for x in passwd: if x.isupper()==True: print 'upper' upper+=1 elif x.islower()==True: print 'lower' lower+=1 elif x.isalpha()==False: print 'num' number+=1 if len(passwd) < 7 or upper <= 0 or lower <= 0 or number <= 0: print ('password not complex enough') passwd = raw_input('please enter password again ') upper = 0 lower = 0 number = 0 else: break print 'final password:', passwd 

Salida:

 enter your password: pA lower upper password not complex enough please enter password again pA1ghlfx78 lower upper num lower lower lower lower lower num num final password: pA1ghlfx78 

Puede simplificar toda la lógica utilizando unicodedata.category para recostackr qué categoría de un personaje es y luego verificar si están presentes todos los datos esperados, por ejemplo:

 import unicodedata is_valid = ( len(password) >= 7 and {'Ll', 'Lu', 'Nd'}.issubset(unicodedata.category(ch) for ch in password) ) 

Si una contraseña debe constar solo de letras y números ASCII , entonces el enfoque más eficiente sería utilizar conjuntos :

 from string import ascii_lowercase, ascii_uppercase, digits def is_valid(password): if len(password) < 7: return False password_set = set(password) return not any(password_set.isdisjoint(x) for x in (ascii_lowercase, ascii_uppercase, digits)) 

Si se permiten caracteres Unicode, puede usar any() :

  def is_valid(password): return (len(password) >= 7 and any(c.islower() for c in password) and any(c.isupper() for c in password) and any(c.isdigit() for c in password)) 

Puede que esto sea útil para usted. Uso sum(1 for c in the string if c.islower()) para encontrar el número total de minúsculas. y de la misma manera para encontrar el número total de mayúsculas y dígitos. len(string) para encontrar la longitud de la cadena.

 string=input() if ((sum(1 for c in string if c.islower())>=1) and (sum(1 for c in string if c.isupper())>=1) and (sum(1 for c in string if c.isdigit())>=1) and (len(string)>=7)): print("Password is complex") else: print ("Password not complex enough")