- Obtener enlace
- Correo electrónico
- Otras aplicaciones
Entrada destacada
- Obtener enlace
- Correo electrónico
- Otras aplicaciones
En una entrada anterior de este blog vimos como programar el Cifrado César, pero ahora veremos como hacerlo de una manera un tanto más complejo, ya que en este ejemplo no solo cifraremos texto, también se verá como descifrar un código, y como hacerlo con un método de fuerza bruta.
En el ejemplo antes mencionado usabamos listas para almacenar las letras del abecedario, pero en esta ocasión usaremos el correspondiente código ASCII del caracter o también llamado valor ordinal entero.
Empecemos creando un menú, que pida al usuario elegir entre Cifrar o Descifrar.
def menuPrincipal(): while True: print("================================== ") print("========= CIFRADO CESAR ========== ") print("================================== ") print("== a) Cifrar == ") print("== b) Decifrar == ") print("== c) Decifrar por fuerza bruta == ") print("== x) Salir == ") print("================================== ") opcion = input().lower(); if opcion in "a,b,c,x".split(','): return opcion
La entrada que se obtiene siempre se convierte a minúsculas, así no importara si las mayúsculas están activadas. Se valida que la letra introducida sea una opción valida y entonces si es una opción valida retorna el string de entrada.
Si la opción introducida es a) o b) se solicita es texto que se va cifrar o descifrar.
La siguiente función solicita al usuario cuando posiciones se moverá en el alfabeto, suponiendo que el mensaje introducido sea "abc" y seleccionamos cifrar y como clave elegimos 2 el resultado sería "cde".
Usamos un while para repetir el mensaje en caso que la clave introducida no este dentro del rango. TAM_MAX_CLAVE fue inicializada con un valor de 26 que son el número de caracteres entre a y z, si el valor introducido es un posición valida sale del ciclo y devuelve el valor.
Para cifrar y descifrar usamos la siguiente función, la cual recibe como parámetros:
Finalmente ejecutamos las funciones según sea la selección de opciones del usuario, como vemos para hacer el descifrado por fuerza bruta es probar con todas las claves posibles y mostrar todas las traducciones.
Código fuente completo de CifradoCesar.py
Comenta tus dudas en la sección de comentarios.
Si la opción introducida es a) o b) se solicita es texto que se va cifrar o descifrar.
def obtenerMensaje(): print('Ingresa tu mensaje:') return input()
La siguiente función solicita al usuario cuando posiciones se moverá en el alfabeto, suponiendo que el mensaje introducido sea "abc" y seleccionamos cifrar y como clave elegimos 2 el resultado sería "cde".
def obtenerClave(): clave = 0 while True: print('Ingresa el número de clave (1-%s)' % (TAM_MAX_CLAVE)) clave = int(input()) if(clave >= 1 and clave <= TAM_MAX_CLAVE): return clave
Para cifrar y descifrar usamos la siguiente función, la cual recibe como parámetros:
- la opcion (sea a o b),
- el mensaje y
- la clave
Comprobamos si la opción es 'b' (descifrar) pasamos a negativo el valor de la clave de lo contrario la clave queda tal cual. Con la ayuda de un for recorremos el mensaje como si de una lista se tratara, símbolo contendrá cada letra del mensaje por cada iteración. En cada ciclo comprobamos si el caracter pertenece al alfabeto (o sea que no sea numérico o caracteres especiales) de lo contrario simplemente se deja pasar con su valor original. Con la función ord obtenemos el valor ordinal del caracter, que es un valor numérico.
Por ejemplo A = 65 y si la clave es 2 la suma valor será 67.
Con chr hacemos lo inverso, mediante un valor ordinal obtenemos su correspondiente caracter 67 = C.
Por ejemplo A = 65 y si la clave es 2 la suma valor será 67.
Con chr hacemos lo inverso, mediante un valor ordinal obtenemos su correspondiente caracter 67 = C.
Las comprobaciones simbolo.isupper y simbolo.islower comprueban si el símbolo es mayúscula o minúscula, para cualquiera de los dos casos se verifica si el valor ordinal obtenido está fuera del alfabeto, si lo estuviera tendríamos que volver al inicio y contar aparir de ahí.
Suponiendo que el mensaje introducido sea 'Z' = 90 y la clave seleccionada sea 2 la suma seria 92 el cual corresponde a '\'. Entonces lo que hacemos es restar a esa suma el número de caracteres existentes en el alfabeto 92 - 26 = 66 el cual corresponde a 'B' lo mismo pasa si se trata de descifrar y el valor obtenido es menor al valor ordinal de A o a.
Suponiendo que el mensaje introducido sea 'Z' = 90 y la clave seleccionada sea 2 la suma seria 92 el cual corresponde a '\'. Entonces lo que hacemos es restar a esa suma el número de caracteres existentes en el alfabeto 92 - 26 = 66 el cual corresponde a 'B' lo mismo pasa si se trata de descifrar y el valor obtenido es menor al valor ordinal de A o a.
def traducirMensaje(opcion, mensaje, clave): if opcion == 'b': clave = -clave traduccion = '' for simbolo in mensaje: if simbolo.isalpha(): num = ord(simbolo) num += clave if simbolo.isupper(): if num > ord('Z'): num -= 26 elif num < ord('A'): num += 26 elif simbolo.islower(): if num > ord('z'): num -= 26 elif num < ord('a'): num += 26 traduccion += chr(num) else: traduccion += simbolo return traduccion
Finalmente ejecutamos las funciones según sea la selección de opciones del usuario, como vemos para hacer el descifrado por fuerza bruta es probar con todas las claves posibles y mostrar todas las traducciones.
def main(): while True: opcion = menuPrincipal() if opcion == 'x': break mensaje = obtenerMensaje() if opcion == 'c': print('Tu texto traducido es:') for clave in range(1, TAM_MAX_CLAVE): print(clave, traducirMensaje(opcion, mensaje, clave)); else: clave = obtenerClave() print('Tu texto traducido es:') print(traducirMensaje(opcion, mensaje, clave));
Código fuente completo de CifradoCesar.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | TAM_MAX_CLAVE = 26 def menuPrincipal(): while True: print("================================== ") print("========= CIFRADO CESAR ========== ") print("================================== ") print("== a) Cifrar == ") print("== b) Decifrar == ") print("== c) Decifrar por fuerza bruta == ") print("== x) Salir == ") print("================================== ") opcion = input().lower(); if opcion in "a,b,c,x".split(','): return opcion def obtenerMensaje(): print('Ingresa tu mensaje:') return input() def obtenerClave(): clave = 0 while True: print('Ingresa el número de clave (1-%s)' % (TAM_MAX_CLAVE)) clave = int(input()) if(clave >= 1 and clave <= TAM_MAX_CLAVE): return clave def traducirMensaje(opcion, mensaje, clave): if opcion == 'b': clave = -clave traduccion = '' for simbolo in mensaje: if simbolo.isalpha(): num = ord(simbolo) num += clave if simbolo.isupper(): if num > ord('Z'): num -= 26 elif num < ord('A'): num += 26 elif simbolo.islower(): if num > ord('z'): num -= 26 elif num < ord('a'): num += 26 traduccion += chr(num) else: traduccion += simbolo return traduccion def main(): while True: opcion = menuPrincipal() if opcion == 'x': break mensaje = obtenerMensaje() if opcion == 'c': print('Tu texto traducido es:') for clave in range(1, TAM_MAX_CLAVE): print(clave, traducirMensaje(opcion, mensaje, clave)); else: clave = obtenerClave() print('Tu texto traducido es:') print(traducirMensaje(opcion, mensaje, clave)); if __name__ == "__main__": main() |
Comenta tus dudas en la sección de comentarios.
- Obtener enlace
- Correo electrónico
- Otras aplicaciones
Comentarios
Publicar un comentario