Encriptar un mensaje es modificarlo de forma que si alguien que no conoce la clave intenta leerlo no va a poder hacerlo.
La criptografía se usa desde hace miles de años, un gran ejemplo es cuándo Julio Cesar por ejemplo encriptaba mensajes simplemente modificando el orden de las letras.
Hagamos un ejemplo de encriptación de mensajes sencillo, piensa en él más como un juego que como una forma real de cifrar mensajes ya que en este momento con los avances tecnológicos los computadores son tan veloces que lo descifrarían muy rápidamente.
Hay API's de cifrado de mensajes mas especializadas y complejas que podemos usar.
Si utilizas python 3.x te puede dar un error “AttributeError”, esto se da porque en la linea 95:
for key, value inKEYS.iteritems():
lo debes remplazar por:
for key, value inKEYS.items():
y tambien en lugar de usar:
raw_input()
usa:
input()
Muchas gracias “kuronosu” por el dato de cambiar iteritems por items
gracias
Saludo a todos!
Quiero proponer un algoritmo un poco diferente. Y es que no le encuentro mucho sentido separar en palabras el mensaje y luego en letras para luego realizar el cambio de caracteres.
Considero que hacerlo de esa manera es crear procesos de computo innecesarios, ya que python al igual que otros lenguajes como Ruby y Go las variables de tipo String las trabajan internamente como un Array y como tales podemos iterar entre sus caracteres haciendo uso de un indice, siendo los espacios en blanco un carácter más.
Por tal razón propongo un algoritmo en el que agrego en el diccionario un carácter más para los espacios en blanco e iterando directamente sobre el mensaje, dejando a un lado operaciones innecesarias.
Con ese pequeño detalle logre hacer los métodos cypher y decipher más eficientes y sobre todo más legibles, aquí se los dejo a ver que me dicen!!
# -*- coding: utf-8-*-#importamos la función time para capturar tiempos
from time import time
KEYS={'a':'w','b':'E','c':'x','d':'1','e':'a','f':'t','g':'0','h':'C','i':'b','j':'!','k':'z','l':'8','m':'M','n':'I','o':'d','p':'.','q':'U','r':'Y','s':'i','t':'3','u':',','v':'J','w':'N','x':'f','y':'m','z':'W','A':'G','B':'S','C':'j','D':'n','E':'s','F':'Q','G':'o','H':'e','I':'u','J':'g','K':'2','L':'9','M':'A','N':'5','O':'4','P':'?','Q':'c','R':'r','S':'O','T':'P','U':'h','V':'6','W':'q','X':'H','Y':'R','Z':'l','0':'k','1':'7','2':'X','3':'L','4':'p','5':'v','6':'T','7':'V','8':'y','9':'K','.':'Z',',':'D','?':'F','!':'B',' ':'&',}def cypher(message): cypher_message =""for letter inmessage: cypher_message +=KEYS[letter]return cypher_message
def decipher(message): decipher_message ='' i =0for letter inmessage:for key, value inKEYS.items():if value == letter: decipher_message += key
i+=i
return decipher_message
def run():whileTrue: command =str(raw_input('''---*---*---*---*---*---*---*---Bienvenido a criptografía.¿Qué deseas hacer?[c]ifrar mensaje
[d]ecifrar mensaje
[s]alir
'''))if command =='c': message =str(raw_input('Escribe tu mensaje: ')) cypher_message =cypher(message)print(cypher_message) elif command =='d': message =str(raw_input('Escribe tu mensaje cifrado: ')) decypher_message =decipher(message)print(decypher_message) elif command =='s':print('salir')breakelse:print('¡Comando no encontrado!')if __name__ =='__main__':print('M E N S A J E S C I F R A D O S')run()
Me gusto tu propuesta, solo tengo una pregunta por que dentro del metodo decipher declaraste la variable i y dentro del ciclo lo unico que haces es volver a introducir el mismo valor en la misma varible…
Talvez en una de tus ideas se te olvido borrar esa varible, es lo mas probable 😃
Saludos! Z4kro te cuento que esas dos lineas a las que haces referencia se me pasó borrarlas por que en realidad no hacen nada.
Lo otro que quiero decirte es que no estoy ingresando el mismo valor en la misma variable, estoy contando las veces que se ejecuta el ciclo (i es un contador), i += i es igual a escribir contador = contador + 1.
Gracias por tu comentario ya que no me había dado cuenta de ese detalle. Éxito en todos tus estudios Platzi.
Muy buen código , me encanto esta clase. Se hace un poco complicada la función de desencriptar pero al final se acaba entendiendo( estuve un rato , no te creas jajaja) Solo un apunte para quien quiera dejar terminado el codigo falta añadir la funcion de salie en el codigo :
Importar la libreria sys
diccionario.items(), diccionario.keys(), y diccionario.values()
Justo estaba pensando eso, gracias por la info :D
Mil Gracias!
En python 3 es KEYS.item no KEYS.iteritems
Gracias!
Gracias por tu comentario. Fue de gran ayuda.
Para python 3 debes cambiar:
KEYS.iteritems():
por
KEYS.items():
También recuerda cambiar los raw_input por input y cuida la identación en los ciclos o no resultará.
EXPLICACION PASO A PASO DEL CODIGO
#CLASE27CURSODEPYTHON-IMPLEMENTARBUSQUEDABINARIAENPYTHON"""Vaamo a utlizar los dicionarios para cifrar y desfrirar palabras, para ello crearemos un diccionario
que ser "KEYS" donde pondremos el valor de cada palabra para cunado cifremos el mensaje.Despus tendremos una funcion principal que sera "def run" y dentro de ella haremos llamar la funciones
de cifrar y descifrar dependiedno de lo que uqeramos hacer y estas dos funciones las desarrollaermos
por separado con su respectivo bloque de codigo """
KEYS={'a':'w','b':'E','c':'x','d':'1','e':'a','f':'t','g':'0','h':'C','i':'b','j':'!','k':'z','l':'8','m':'M','n':'I','o':'d','p':'.','q':'U','r':'Y','s':'i','t':'3','u':',','v':'J','w':'N','x':'f','y':'m','z':'W','A':'G','B':'S','C':'j','D':'n','E':'s','F':'Q','G':'o','H':'e','I':'u','J':'g','K':'2','L':'9','M':'A','N':'5','O':'4','P':'?','Q':'c','R':'r','S':'O','T':'P','U':'h','V':'6','W':'q','X':'H','Y':'R','Z':'l','0':'k','1':'7','2':'X','3':'L','4':'p','5':'v','6':'T','7':'V','8':'y','9':'K','.':'Z',',':'D','?':'F','!':'B',}"""Empezamos con la función principal "def run" dentro de ella ejecutaremos un "loop while" que ser infinito
por eso lo inicializamos en "True" para que itere hsata que se cumpla lo que queremos
Dentro de este "loop while" cremoa una primera variable "command" que sera la encargada de preguntarnos
en la consola que funcion queremso ejecutar para asi el codigo ejecutar la de cifrar mensaje o descifrar
el mensaje, despues creamos los condiciones para saber que hemos seleccionado y dentro de cada condicional
ira su repsectivo codigo que se encargue de ejecutar la funcion que tenga en fuuncion a lo que queramos
conseguir
"""
def run():whileTrue: command =str(input('''---*---*---*---*---*---*---*---Bienvenidos a criptografia.Que deseas hacer?[c]ifrar mensaje
[d]ecifrar mensaje
[s]alir
'''))"""Este condicional se encargar del codigo cuando elegimo cifrar, detro de ella tenemos dos variables
-message: que es la variable donde estara guarda el mensaje que hayamos escrito en la consola para cifrar
-cypher_message: es donde esta guardad la funcion "cypher(message)" que se encargar de cifrar el mensjae
por eso la variable con el mensaje guardado esta como parametor de la función """
if command =='c': message =str(input('Escribe tu mensaje: ')) cypher_message =cypher(message)print(cypher_message)"""En este condiconal haremos lo mismo que en el "if" pero al contrario, cogeremos el mensaje ya cifrado
por la funcion "cypher" y con la nueva funcion "decipher(message) se encargar de descifrar el mensaje cifrado
"""
elif command =='d': message =str(input('Escribe tu mensaje cifrado: ')) decypher_message =decipher(message)print(decypher_message) elif command =='s':print('salir')else:print('Comando no encotrado')"""Esta es la función en cargada de cifrar el mensaje
-Con la variable "words" lo que haremosa sera coger la frase guardada en "message" y separarla
por sus espacios osea por sus palabras, lo haremos a traves de "split"-Crearemos la lista vacia "cypher_message[]" donde se ira guardando el resultado que salga del
ciclo "for" que se encargara de ver si cada letra de la palabra esta dentro del diciionario "KEYS"y poner el valor a que equivale esa letra en el diccionario """
def cypher(message): words = message.split(' ') cypher_message =[]"""Con este ciclo vamos a iterar a lo largo de las palabras, crearemos una variable vacia que sera
"cypher_word"El ciclo "for letter in word" lo que dice es que iterara cada letra de cada palabra, con cada una de
esas iteraciones a traves de "kEYS[letter]" lo que estamos diciendo es que de cada letra busque en
el diccionario las llaves que tenga el valor de esa letra y atraves de "+=" iremos añadiendo ese resultado
a la varible vaica "cypher_wor"A traves de "append" añadiremos el resultado de "cypher_word" a "cypher_message" y en "return" a traves
de la funcion "join" juntaremos estas palabras que habiamos separado con "split""""
for word inwords: cypher_word =''for letter inword: cypher_word +=KEYS[letter] cypher_message.append(cypher_word)return' '.join(cypher_message)"""Esta es la función que se encargue de descifrar el codigo cifrado, es lo mismo que la funcion de
cifrar pero del reves, tambien separaemos por palabras a traves de "split" y crearemos una lista vaica
donde se añadira el resultado del ciclo "for""""
def decipher(message): words = message.split(' ') decipher_message =[]"""Creamos nuestra variable vacia "decipher_word" que iremos yenando con los valores del siguiente ciclo
for, lo que decimos con este ciclo es que por cada palabra de las palabras tendremos una variabel
vaica, volveremos a iterar ahora por cada letra de la palabra
El tercer "for" es mas complicado porque ahora no podemos acceder al diccionario a traves de su valor
tendremos que iterar a lo largo de todas las llaves y si encontramos el valor entocnes podremos obtener la
llave.Para obtener tanto las llaves "key" como el valor de las llaves "value" utilizaremos "KESY.items"con if lo que decimos es que una si el valores igual a la letra entonces encontramos la letra a la que
corresponde añadirmeos a traves de "+=" en la variable vacia "decipher_word"Para entendrlo bien el diccionario consta de llaves y valores, ahora mismo tenrmos el valor del diccionario
y necesitamos la llave que esquivale a ese valor, si nuestra letra equivale algun valor habremos encontrado
la llave junto con la letra a la que representa y eso lo aremos con la funcion "items"DEspues solo tenemos que añadirlo a lista vaica "decipher_message" a traves de "append" y con "join"unir las palabras
"""
for word inwords: decipher_word =''for letter inword:for key, value inKEYS.items():if value == letter: decipher_word += key
decipher_message.append(decipher_word)return' '.join(decipher_message)if __name__ =='__main__':print('MENSAJES DIFRADOS')run()```
Hola comunidad, me emocione mucho con este ejercicio y me puse a hacer cosas locas, en el programa que realice ahora la llave de cifrado la crea aleatoriamente el programa por lo cual nunca es la misma, y si quieres decifrar el mensaje tienes que ingresar el password correctamente.
No fue facil pero he aplicado todo lo que he aprendido hasta ahora, Gracias @David Aoresti!!!
# -*- coding: utf-8-*-import random
#crea el abecedario y lo pone en una lista
def alphabet(): abcd=list(map(chr,range(32,127)))return abcd
#crea la llave de cifrado y la pone en una lista
def createKey(): abcd=alphabet() criptographicKey=list(abcd) noRepeted=[random.randint(0,94)]for i inrange(0,len(criptographicKey),1): criptographicKey[i]=abcd[assigment(noRepeted)]return criptographicKey
#debido a que se utiliza el comando random las letras se repiten
#esta funcion evita letras repetidas en la llave de cifrado
def assigment(noRepeted):iflen(noRepeted)<95: repeted=0 assig=random.randint(0,94)for i inrange(0,len(noRepeted),1):if noRepeted[i]==assig: repeted+=1breakif repeted==0: noRepeted.append(assig)return assig
else:returnassigment(noRepeted)else:return0
#cifra el mensaje
def cypher(msg_lst,abcd,criptographicKey): encriptedMsg=[]for i inrange(0,len(msg_lst),1):for j inrange(0,len(abcd),1):if msg_lst[i]==abcd[j]: encriptedMsg.append(criptographicKey[j])breakprint('\nCypher message:\n\t', end='')print(''.join(encriptedMsg))return encriptedMsg
#descifra el mensaje
def Decypher(encriptedMsg,RealKey,abcd): deEncriptedMsg=[]for i inrange(0,len(encriptedMsg),1):for j inrange(0,len(RealKey),1):if encriptedMsg[i]==RealKey[j]: deEncriptedMsg.append(abcd[j])breakprint('Decypher message:\n\t', end='')print(''.join(deEncriptedMsg))return deEncriptedMsg
def run(): #password
MASTER_KEY='PLATZI'
#genera el abcdario
abcd=list(alphabet()) #genera la llave de cifrado real
RealKey=createKey() msg=str(input('\nType the massage:')) msg_lst=list(msg)print('\nMessage:\n\t', end='')print(''.join(msg_lst))
#si ingresas el password incorrecto se crea una llave de
#cifrado falsa y no podras volver a descifrar el msj
ask_master_key=str(input('\nPassword:'))ifMASTER_KEY==ask_master_key: criptographicKey=list(RealKey)else: criptographicKey=createKey()
#cifrar
encriptedMsg=cypher(msg_lst,abcd,criptographicKey)
#descifrar
print('\nDecyphering...')input() deEncriptedMsg=Decypher(encriptedMsg,RealKey,abcd)if __name__=='__main__':run()```
Mega genial tu aporte!! Muchas gracias.
Gracias Mateo me alegra que te guste!! ✌️
Aquí mi aporte de diccionarios para código morse :D. Si alguno puede añadir que no tradusca nada si no se encuentra en el diccionario seria genial, ya son las 2 am y no tengo cabeza para eso
<# -*- coding: utf-8-*-#region Importancionesimport tkinter # Libreria para messageboxes
import tkinter.messageboxasMessageBox # Libreria messagebox de tkinter con un alias
import json #gracias a esta libreria podemos utilizar regiones en python
#endregion Importaciones
#region dictionario morse
dicMorse={"a":".-","b":"-...","c":"-.-.","d":"-..","e":".","f":"..-.","g":"--.","h":"....","i":"..","j":".---","k":"-.-","l":".-..","m":"--","n":"-.","ñ":"--.--","o":"---","p":".--.","q":"--.-","r":".-.","s":"...","t":"-","u":"..-","v":"...-","w":".--","x":"-..-","y":"-.--","z":"--..","1":".----","2":"..---","3":"...--","4":"....-","5":".....","6":"-....","7":"--...","8":"---..","9":"----.","0":"-----",":":"---...",",":"--..--",";":"-.-.-.","?":"..--..","-":"-....-","_":"..--.-","+":".-.-.","=":"-...-","@":".--.-.",".":".-.-.-"}#endregion dictionario morse
#region metodos a nivel de modulo
def insertInput(_strSentence):try: _strSentence=str(input("Ingrese la oración: ")) aVowels,uVowels ='áéíóúü','aeiouu' # declaracionde dos variables.vocales con acentos y vocales sin los acentos
trans = str.maketrans(aVowels,uVowels) # retorna una tabla de traduccion
var=_strSentence.translate(trans) # reemplaza cada caracter en la cadena con la tabla de traduccion dada
returnvar.lower() # retornamos la cadena en minusculas
except:MessageBox.showerror(title="Error de inicialización", message="Error al ingresar por teclado la cadena") #msgbox si hay errores
returnFalsedef translateToMorse(_strSentence): strSentenceTranslated="" # inicializacion de variable local
for word in_strSentence:for letter inword:if(letter!=" "): # Si encuentra espacios en blanco no concatena nada
strSentenceTranslated=strSentenceTranslated+dicMorse[letter] strSentenceTranslated=strSentenceTranslated+" " # al final de cada palabra dejame 3 espacios en blanco
return strSentenceTranslated
#endregion metodos a nivel de modulo
#region metodo main
if __name__=="__main__":"""
1.Pediremos un mensaje por teclado
2.Se transformara cada letra de cada palabra del mensaje a morse
3.Entre cada letra habra un espacio, mientras que entre cada palabra habrá tres espacios
5.Se imprimira en pantalla el mensaje en código morse
"""
window= tkinter.Tk() # Requirido.window.wm_withdraw() # Para ocultar window una ves usado.print("---- Traductor de lenguaje español/inglés a código morse ----")try: strSentence="" strSentence=insertInput(strSentence) # pedimos que se ingrese por teclado la oración
if(strSentence==False):print("No se ingreso una cadena valida")else: strSentenceTranslated=translateToMorse(strSentence)print(strSentenceTranslated)input("")except:MessageBox.showerror(title="Error de ejecución", message="Error al ejectuar el programa") #msgbox si hay errores
input("")#endregion metodo main
>
muchachos recuerden los que usen python 3 y versiones superiores que iteritems() ya se removio de estas versiones. Ahora se usa items(). tambien estan disponibles diccionario.keys() y diccionario.values()
creo que se le olvido enseñarnos a que salir, cumpliera con la funcion de salir jejeje
Se puede usar break
elif command =='s':print('Regresa pronto')break
Puede ser tambien
elif command =='s':print('Regresa pronto')exit()
Estoy trabajando en la versión 3.7.4 de python y el método no es iteritems sino items.
quedaría:
for key, value in KEYS.items():
gracias por el recordatorio
Para los que no les funcione el metodo iteritems() en python 3-x, es porque se debe cambiar a items().
Saludos
Para aquellos que les aparezca el error, AttributeError: 'dict' object has no attribute 'iteritems', es porque en python 3 eliminaron el iteritems, solo pongan el items, osea , KEYS.items()
en python 3.x items() sse usa en ves de de iteritems()
Correcto gracias, ya estaba vovliendo loco al no ver mi error
Me parecio mas simple no dividir por palabras, y por si no existe la Key le dejé la real.
KEYS={'a':'w','b':'E','c':'x','d':'1','e':'a','f':'t','g':'0','h':'C','i':'b','j':'!','k':'z','l':'8','m':'M','n':'I','o':'d','p':'.','q':'U','r':'Y','s':'i','t':'3','u':',','v':'J','w':'N','x':'f','y':'m','z':'W','A':'G','B':'S','C':'j','D':'n','E':'s','F':'Q','G':'o','H':'e','I':'u','J':'g','K':'2','L':'9','M':'A','N':'5','O':'4','P':'?','Q':'c','R':'r','S':'O','T':'P','U':'h','V':'6','W':'q','X':'H','Y':'R','Z':'l','0':'k','1':'7','2':'X','3':'L','4':'p','5':'v','6':'T','7':'V','8':'y','9':'K','.':'Z',',':'D','?':'F','!':'B',}def encriptar(mensajeInput): ret =''for caracter inmensajeInput:if caracter inKEYS: ret +=KEYS[caracter]else: ret += caracter
return ret
def getKey(caracter):for key, value inKEYS.items():if caracter == value:return key
return caracter
def desencriptar(mensajeEncriptado): ret =''for caracter inmensajeEncriptado: ret +=getKey(caracter)return ret
def main():whileTrue: userInput =str(input('''
Bienvenido!Elegí la opcion del menu que queres probar.[e]ncriptar mensaje
[d]esencriptar mensaje
[s]alir
Input:'''))if userInput =='e' or userInput =='E': mensajeInput =str(input('\nIngrese su mensaje: ')) mensajeEncriptado =encriptar(mensajeInput)print(mensajeEncriptado) elif userInput =='d' or userInput =='D': mensajeInput =str(input('\nIngrese su mensaje cifrado: ')) mensajeDesencriptado =desencriptar(mensajeInput)print(mensajeDesencriptado) elif userInput =='s' or userInput =='S':print('\npusiste Salir')exit()else:print('\nComando no reconocido')if __name__ =='__main__':main()```
Hola si usando python 3 solo debes poner items(), ya que iteritems solo funciona en python 2.
Saludos desde Peú
No está de más hacer un aporte, para quienes quizá quieren limpiar la consola como lo hace el profesor para mi caso que uso windows lo hago así
quit()
cls
y ya con eso te queda limpia la pantalla.
Hay que recalcar que todo este tiempo en Python 3.xxx hemos tenido que venir usando input en vez de raw_input y ahora en este caso ya no se utiliza la función iteritems sino que se usa la función items