Soy relativamente nuevo con Python y estoy haciendo un programa donde recibimos una cadena de 3 letras con una letra mayúscula, una letra minúscula y un número en cualquier orden. Se supone que el programa lo encontrará a través de un ataque de fuerza bruta.
He intentado hacer esto para bucles y definir las letras mayúsculas y minúsculas y las letras como cadenas y luego intentar iterar a través de ellas para bucles for y tratar de hacer coincidir las letras de la cadena que queríamos encontrar con las letras mayúsculas y minúsculas o números en consecuencia.
Lo que intenté hacer:
uppers="ABCDEFGHIJ"
lowers="abcdefghij"
numbers="1234567890"
secret="Je1" #The string the computer is supposed to find through a brute-force attack
password = ""
counter = 0
for upper in uppers:
if upper in secret:
password += upper
break
else:
counter += 1
for lower in lowers:
if lower in secret:
password += lower
break
else:
counter += 1
for number in numbers:
if number in secret:
password += number
break
else:
counter += 1
print(password)
print("Counter: {0}".format(counter))
Cuando ejecuto el código, funciona, pero solo cuando la cadena secret está en un orden diferente al de mayúsculas, minúsculas y números ("Je1" funciona, "eJ1" no). El programa realmente no hace su función correctamente sin reorganizar los bucles for en consecuencia.
¡Cualquier ayuda es muy apreciada!
4 respuestas
Su código muy específicamente siempre genera mayúsculas, minúsculas y números exactamente en este orden, independientemente de la entrada.
Esto es posible de solucionar de varias maneras, cada una con algunas compensaciones.
Lo más simple es hacer fuerza bruta, es decir, examinar los tres conjuntos en cada posición.
Como optimización, puede eliminar la categoría en la que encontró una coincidencia de las iteraciones posteriores, reduciendo el espacio de búsqueda a medida que avanza. Es poco probable que esto sea escalable a problemas del mundo real, donde el espacio de búsqueda es más complejo (no sabe si habrá una o más apariciones de caracteres en cualquier categoría, excepto si una categoría aún no ha sido certificada por cerca de El final de la cadena).
Alternativamente, puede recordar en qué posición encontró un personaje en una categoría particular y volver a armar la contraseña en el orden correcto al final con esta información. En cierto sentido, esta es la solución más elegante, pero nuevamente, tiene el problema de que no será muy útil en un programa de descifrado de contraseñas del mundo real.
En otras palabras, la solución de "fuerza bruta completa" es la más escalable, ya que escalará a problemas del mundo real, a pesar de que es computacionalmente la menos escalable.
En el futuro, piense en cómo podría enumerar todas las contraseñas posibles en el espacio de búsqueda, para que cada candidato de contraseña obtenga un índice predecible, y simplemente repita esa enumeración.
Una manera fácil de lograr esto en Python es usar itertools.permutations . Esto le brinda todas las combinaciones posibles de una determinada colección de artículos.
En su caso, la "colección de elementos" son todas las letras minúsculas, mayúsculas y números. Por lo tanto, para usar permutations
, debes juntarlos en una sola colección. Para esto, solo puede concatenar las cadenas juntas:
chars = uppers + lowers + numbers
O simplemente definirlas como una cadena:
chars = "ABCDEFGHIJabcdefghij1234567890"
Luego puede ejecutar permutations(chars, 3)
que le da elementos de 3 caracteres de longitud como una tupla. Un ejemplo sería ('a', 'C', '3')
. Necesita comparar esto con la cadena de contraseña. Puede dividir la cadena de contraseña en una tupla (que debe hacerse una vez) o unir la tupla de permutación en una cadena (que debe hacerse para cada elemento). En su caso, supongo que desea usar la contraseña generada para algo, así que unamos la tupla en una cadena, que nos da el siguiente código:
from itertools import permutations
uppers="ABCDEFGHIJ"
lowers="abcdefghij"
numbers="1234567890"
secret="Je1"
for candidate in permutations(uppers + lowers + numbers, 3):
if ''.join(candidate) == secret:
print(candidate)
El siguiente programa es ligeramente ineficiente pero funciona para su propósito.
import re
def m(secret):
import re
if len(secret)==3 and re.search(r'[A-Z]', secret) and re.search(r'[a-z]', secret) and re.search(r'[0-9]', secret):
print "Yes"
else:
print "No"
Que se puede modificar aún más utilizando positive lookaheads
como se menciona en la respuesta aceptada de Match regex en cualquier pedido
if re.search(r"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{3}$", secret):
print "Yes"
else:
print "No"
Está haciendo un bucle en el orden superior, inferior, número, por lo que solo puede hacer coincidir las cadenas que están en ese orden específico. Necesita hacer un bucle en todas las permutaciones posibles de número superior, inferior. Es decir, debe repetir lo que hizo para estas permutaciones:
Superior, número, inferior
inferior, superior, número
inferior, número, superior
número, inferior, superior
número, superior, inferior
Puedes acortar tus tres bucles de esta manera:
for upper in uppers:
for lower in lowers:
for number in numbers:
password = upper + lower + number
if password == secret:
print('Matched. Secret is', secret)
Repita esto cinco veces más cambiando el orden del número superior, inferior,.
O bien, puede usar el paquete itertools
para evitar tener que repetir tantas veces.
from itertools import permutations
for upper in uppers:
for lower in lowers:
for number in numbers:
perms = list(permutations([upper, lower, number]))
if tuple(secret) in perms:
print('Matched. Secret is', secret)
Preguntas relacionadas
Preguntas vinculadas
Nuevas preguntas
python
Python es un lenguaje de programación multipropósito, de tipificación dinámica y de múltiples paradigmas. Está diseñado para ser rápido de aprender, comprender y usar, y hacer cumplir una sintaxis limpia y uniforme. Tenga en cuenta que Python 2 está oficialmente fuera de soporte a partir del 01-01-2020. Aún así, para preguntas de Python específicas de la versión, agregue la etiqueta [python-2.7] o [python-3.x]. Cuando utilice una variante de Python (por ejemplo, Jython, PyPy) o una biblioteca (por ejemplo, Pandas y NumPy), inclúyala en las etiquetas.