Skip to content

Instantly share code, notes, and snippets.

@iordic
Created October 29, 2019 10:23
Show Gist options
  • Save iordic/dd46b7fd959c6227f2ca493dfb954716 to your computer and use it in GitHub Desktop.
Save iordic/dd46b7fd959c6227f2ca493dfb954716 to your computer and use it in GitHub Desktop.
Reto propuesto con cifrado improvisado
"""
1. Pasar a texto el pin: "elpindelatarjetaesunodostrescuatro"
2. ROT-13 a cada caracter
3. Convertir a posición del alfabeto en número
4. Convertir a binario
5. De cada byte del carácter se le suma a cada bit un número de su teléfono (8 últimos dígitos.)
6. se convierte cada resultado a un digito hexadecimal (por si suman 10)
7. se guarda el valor hexadecimal a un fichero
"""
import tkinter as tk
from tkinter import ttk
from tkinter import filedialog
from tkinter import messagebox
FICHERO_RESULTADO = 'resultado.txt'
CIFRAR = 1
DESCIFRAR = 2
sal = "elpindelatarjetaes"
alfabeto = ('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')
digitos = ("cero", "uno", "dos", "tres", "cuatro", "cinco", "seis", "siete", "ocho", "nueve")
class CifrarFrame(ttk.Frame):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.pin_label = ttk.Label(self, text="Pin:")
self.pin_label.grid(pady=5, row=0, column=0)
self.pin_entry = ttk.Entry(self)
self.pin_entry.grid(padx=5, row=0, column=1, columnspan=2)
self.telefono_label = ttk.Label(self, text="Teléfono:")
self.telefono_label.grid(pady=5, row=1, column=0)
self.telefono_entry = ttk.Entry(self)
self.telefono_entry.grid(pady=5, row=1, column=1, columnspan=2)
self.cifrar_button = ttk.Button(self, text="Cifrar", command=self.cifrar)
self.cifrar_button.grid(padx=5, row=2, column=0, columnspan=3)
def cifrar(self):
pin = self.pin_entry.get()
telefono = self.telefono_entry.get()
if pin == "" or telefono == "":
messagebox.showerror(message="Los campos no pueden estar vacíos", title="Error")
return
if len(telefono) != 9:
messagebox.showerror(message="El teléfono debe contener 9 caracteres", title="Error")
return
fichero = filedialog.asksaveasfile(mode='w', filetypes=(("Fichero de texto",".txt"), ("Todos los ficheros", "*.*")))
if fichero is None:
return
cifrado = cifra(pin, telefono)
fichero.write(cifrado)
fichero.close()
messagebox.showinfo(message="Se ha generado el fichero", title="Guardado")
class DescifrarFrame(ttk.Frame):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fichero = None
self.fichero_label = ttk.Label(self, text="Fichero:")
self.fichero_label.grid(pady=5, row=0, column=0)
self.fichero_field = ttk.Label(self, text="", borderwidth=1, relief="groove")
self.fichero_field.grid(padx=5, row=0, column=1)
self.abrir_button = ttk.Button(self, text="Abrir...", command=self.abrir_fichero)
self.abrir_button.grid(padx=5, row=0, column=2)
self.telefono_label = ttk.Label(self, text="Teléfono:")
self.telefono_label.grid(pady=5, row=1, column=0)
self.telefono_entry = ttk.Entry(self)
self.telefono_entry.grid(pady=5, row=1, column=1)
self.cifrar_button = ttk.Button(self, text="Descifrar", command=self.descifrar)
self.cifrar_button.grid(padx=5, row=2, column=0, columnspan=3)
def abrir_fichero(self):
self.fichero = filedialog.askopenfile(mode="r", filetypes=(("Fichero de texto",".txt"), ("Todos los ficheros", "*.*")))
if self.fichero is not None:
self.fichero_field['text'] = self.fichero.name
else:
self.fichero_field['text'] = ""
def descifrar(self):
telefono = self.telefono_entry.get()
if self.fichero is None:
messagebox.showerror(message="No se ha seleccionado un fichero", title="Error")
return
if telefono == "":
messagebox.showerror(message="El campo teléfono no puede estar vacío", title="Error")
return
if len(telefono) != 9:
messagebox.showerror(message="El teléfono debe tener 9 dígitos", title="Error")
return
self.fichero.seek(0)
texto = self.fichero.read()
descifrado = descifra(texto, telefono)
messagebox.showinfo(message="El pin es: " + descifrado, title="Descifrado correcto")
class Application(ttk.Frame):
def __init__(self, main_window):
super().__init__(main_window)
main_window.title("Cifrador")
self.notebook = ttk.Notebook(self)
self.cifrar_frame = CifrarFrame(self.notebook)
self.notebook.add(self.cifrar_frame, text="Cifrar", padding=10)
self.descifrar_frame = DescifrarFrame(self.notebook)
self.notebook.add(self.descifrar_frame, text="Descifrar", padding=10)
self.notebook.pack(padx=10, pady=10)
self.pack()
def main():
main_window = tk.Tk()
app = Application(main_window)
app.mainloop()
def cifra(pin, telefono):
texto = convertir_pin(pin)
n_letras = len(alfabeto)
rotado = ""
for i in texto:
n = alfabeto.index(i)
rotado += alfabeto[(n + 13) % n_letras]
numeros = convertir_caracteres(rotado)
resultado = ""
for i in numeros:
bits = format(i, '08b')
aux = mix_telefono(bits, telefono)
for j in aux:
resultado += format(j, 'x')
return resultado
def descifra(texto, telefono):
telefono = telefono[1:]
if len(telefono) != 8:
print("Error: la longitud del teléfono es incorrecta.")
return
longitud = len(texto)
if longitud % 8 != 0:
print("Error: el número de caracteres del cifrado es incorrecto.")
return
subconjuntos = []
for i in range(0, longitud, 8):
subconjuntos.append(texto[i:i+8])
rotado = ""
n_letras = len(alfabeto)
for i in subconjuntos:
aux = ""
for j in range(0,8):
aux += str(int("0x" + i[j], 0) - int(telefono[j]))
n = int(aux,2) - 1
rotado += alfabeto[(n - 13)]
rotado = rotado.replace(sal, '')
for i in digitos:
if i in rotado:
rotado = rotado.replace(i, str(digitos.index(i)))
return rotado
def mix_telefono(bits, telefono):
resultado = []
telefono = str(telefono[1:])
if len(bits) != 8:
print("Error: debe haber 8 bits para poder transformar.")
return
for i in range(0,8):
resultado.append(int(bits[i]) + int(telefono[i]))
return resultado
def convertir_pin(pin):
aux = str(pin)
resultado = sal
for i in aux:
resultado += digitos[int(i)]
return resultado
def convertir_caracteres(texto):
resultado = []
for i in texto:
resultado.append(alfabeto.index(i) + 1)
return resultado
if __name__ == '__main__':
main()
"""
1. Pasar a texto el pin: "elpindelatarjetaesunodostrescuatro"
2. ROT-13 a cada caracter
3. Convertir a posición del alfabeto en número
4. Convertir a binario
5. De cada byte del carácter se le suma a cada bit un número de su teléfono (8 últimos dígitos.)
6. se convierte cada resultado a un digito hexadecimal (por si suman 10)
7. se guarda el valor hexadecimal a un fichero
"""
import sys
import getopt
FICHERO_RESULTADO = 'resultado.txt'
CIFRAR = 1
DESCIFRAR = 2
sal = "elpindelatarjetaes"
alfabeto = ('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')
digitos = ("cero", "uno", "dos", "tres", "cuatro", "cinco", "seis", "siete", "ocho", "nueve")
def main(args):
try:
opts, args = getopt.getopt(args, "c:d:t:h", ["cifrar=", "descifrar=", "telefono=", "help"])
except getopt.GetOptError as err:
uso()
pin = None
telefono = None
fichero = None
operacion = 0
for opt, arg in opts:
if opt in ('-h', '--help'):
uso()
if opt in ('-c', '--cifrar'):
operacion += CIFRAR
pin = arg
if opt in ('-d', '--descifrar'):
operacion += DESCIFRAR
fichero = arg
if opt in ('-t', '--telefono'):
telefono = arg
if len(telefono) != 9:
print("Error: el teléfono debe tener 9 cifras.")
uso()
if operacion == CIFRAR:
cifrado = cifra(pin, telefono)
fichero = open(FICHERO_RESULTADO, 'w')
fichero.write(cifrado)
fichero.close()
elif operacion == DESCIFRAR:
fichero = open(fichero, 'r')
texto = fichero.read()
fichero.close()
descifrado = descifra(texto, telefono)
print("El pin es: " + descifrado)
else:
uso()
def cifra(pin, telefono):
texto = convertir_pin(pin)
n_letras = len(alfabeto)
rotado = ""
for i in texto:
n = alfabeto.index(i)
rotado += alfabeto[(n + 13) % n_letras]
numeros = convertir_caracteres(rotado)
resultado = ""
for i in numeros:
bits = format(i, '08b')
aux = mix_telefono(bits, telefono)
for j in aux:
resultado += format(j, 'x')
return resultado
def descifra(texto, telefono):
telefono = telefono[1:]
if len(telefono) != 8:
print("Error: la longitud del teléfono es incorrecta.")
return
longitud = len(texto)
if longitud % 8 != 0:
print("Error: el número de caracteres del cifrado es incorrecto.")
return
subconjuntos = []
for i in range(0, longitud, 8):
subconjuntos.append(texto[i:i+8])
rotado = ""
n_letras = len(alfabeto)
for i in subconjuntos:
aux = ""
for j in range(0,8):
aux += str(int("0x" + i[j], 0) - int(telefono[j]))
n = int(aux,2) - 1
rotado += alfabeto[(n - 13)]
rotado = rotado.replace(sal, '')
for i in digitos:
if i in rotado:
rotado = rotado.replace(i, str(digitos.index(i)))
return rotado
def mix_telefono(bits, telefono):
resultado = []
telefono = str(telefono[1:])
if len(bits) != 8:
print("Error: debe haber 8 bits para poder transformar.")
return
for i in range(0,8):
resultado.append(int(bits[i]) + int(telefono[i]))
return resultado
def convertir_pin(pin):
aux = str(pin)
resultado = sal
for i in aux:
resultado += digitos[int(i)]
return resultado
def convertir_caracteres(texto):
resultado = []
for i in texto:
resultado.append(alfabeto.index(i) + 1)
return resultado
def uso():
print("Uso: python3 {} [argumentos] \n".format(sys.argv[0]))
print("Argumentos:")
print("\t-h, --help muestra este mensaje.")
print("\t-c, --cifrar=<pin> cifra el pin pasado por parámetro.")
print("\t-d, --descifra=<fichero> carga el contenido del fichero a descifrar")
print("\t pasado por parámetro.")
print("\t-t, --telefono=<número> número de teléfono (necesario para cifrar")
print("\t o descifrar).")
sys.exit()
if __name__ == '__main__':
if len(sys.argv) > 1:
main(sys.argv[1:])
else:
uso()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment