Continúo poniendo scripts de programación en python para automatizar tareas que tengan relación con la criptografía.
En este post incluyo y comento un script en python para el cifrado y descifrado por transposición columnar doble.
Antes de poner el script, comentar cómo se cifraba y descifraba manualmente.
El cifrado por transposición columnar doble consiste en realizar dos transposiciones columnares simples de forma consecutiva (ver el post anterior donde explico el cifrado y descifrado mediante transposición columnar simple e incluyo un script en python para ello), la segunda de ellas empleando o no la misma clave que en la primera.
Por tanto, sin mayores explicaciones, pongo el script correspondiente:
- Script python del cifrado por transposición columnar doble:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# CIFRADO POR TRANSPOSICIÓN COLUMNAR DOBLE:
#
# Cifra y descifra textos en claro y criptogramas, respectivamente,
# utilizando la transposición columnar doble.
#
# http://mikelgarcialarragan.blogspot.com/
import re
from unicodedata import normalize
# FUNCIÓN DE CIFRADO:
def cifrar(texto, clave):
criptograma=''
if len(texto)%len(clave)==0:
filas=len(texto)//len(clave)
else:
filas=len(texto)//len(clave)+1
texto_claro=[" "]*filas*len(clave)
for i in range(0,len(texto)):
texto_claro[i]=texto[i]
clave_alfabetica_ordenada=sorted(clave)
clave_numerica=[]
for i in range(0,len(clave)):
clave_numerica.append(clave_alfabetica_ordenada.index(clave[i]))
for i in range(1,len(clave)):
for j in range(0,i):
if clave_numerica[i]==clave_numerica[j]:
clave_numerica[i]+=1
for i in range(0,len(clave)):
for j in range(0,filas):
criptograma+=texto_claro[clave_numerica.index(i)+len(clave)*j]
return criptograma.replace(' ','')
# FUNCIÓN DE DESCIFRADO:
def descifrar(texto, clave):
texto_claro=''
if len(texto)%len(clave)==0:
filas=len(texto)//len(clave)
columnas_completas=len(clave)
else:
filas=len(texto)//len(clave)+1
columnas_completas=len(texto)%len(clave)
columnas_incompletas=len(clave)-columnas_completas
clave_alfabetica_ordenada=sorted(clave)
clave_numerica=[]
for i in range(0,len(clave)):
clave_numerica.append(clave_alfabetica_ordenada.index(clave[i]))
for i in range(1,len(clave)):
for j in range(0,i):
if clave_numerica[i]==clave_numerica[j]:
clave_numerica[i]+=1
huecos=[]
for i in range(-1,-columnas_incompletas-1,-1):
huecos.append((clave_numerica[i]*filas)+(filas-1))
huecos=sorted(huecos)
texto_huecos=''
huecos_incluidos=0
for i in range(0,len(texto)):
if i in huecos:
texto_huecos+=' '
huecos_incluidos+=1
if columnas_incompletas-huecos_incluidos!=0:
huecos[huecos_incluidos]=huecos[huecos_incluidos]-huecos_incluidos
texto_huecos+=texto[i]
criptograma=[" "]*filas*len(clave)
for i in range(0,len(texto_huecos)):
criptograma[((i%filas)*len(clave))+(i//filas)]=texto_huecos[i]
for i in range(0,filas):
for j in range(0,len(clave)):
texto_claro+=criptograma[clave_numerica[j]+len(clave)*i]
return texto_claro.replace(' ','')
# MENÚ:
# Se presenta el menú para que se seleccione una opción.
def main():
salir = False
while not salir:
print ("")
print ("*** MENÚ *****************************************")
print ("1. Cifrar.")
print ("2. Descifrar.")
print ("3. Salir.")
print ("")
opcion = input("Por favor, seleccione una opción: ")
if opcion == "1":
print ("")
print ("--- CIFRAR:")
# Cifrar: Se introducen el texto en claro. Se convierten los caracteres a mayúsculas y
# se eliminan de él los espacios, las tildes, diéresis, etc.
texto_claro = clave1 = clave2 = "*"
while not texto_claro.isalpha():
texto_claro = input('Texto en claro a cifrar: ').upper()
texto_claro = texto_claro.replace(' ','')
texto_claro = re.sub(r"([^n\u0300-\u036f]|n(?!\u0303(?![\u0300-\u036f])))[\u0300-\u036f]+",
r"\1", normalize("NFD", texto_claro), 0, re.I)
texto_claro = normalize("NFC", texto_claro)
if texto_claro.isalpha():
print ("[+] Texto en claro a cifrar:", texto_claro)
# Se introduce la clave para la primera transposición. Se convierten los caracteres a mayúsculas y
# se eliminan de ella los espacios, las tildes, diéresis, etc.
while not clave1.isalpha():
clave1 = input('Clave primera transposición: ').upper()
clave1 = clave1.replace(' ','')
clave1 = re.sub(r"([^n\u0300-\u036f]|n(?!\u0303(?![\u0300-\u036f])))[\u0300-\u036f]+",
r"\1", normalize("NFD", clave1), 0, re.I)
clave1 = normalize("NFC", clave1)
if clave1.isalpha():
print ("[+] Clave primera transposición:", clave1)
criptograma = cifrar(texto_claro, clave1)
misma_clave = ""
while misma_clave !="S" and misma_clave !="N":
misma_clave = input('¿Utilizar la misma clave para la segunda transposición (S/N)?: ').upper()
if misma_clave == "N":
# Se introduce la clave para la segunda transposición. Se convierten los caracteres a mayúsculas y
# se eliminan de ella los espacios, las tildes, diéresis, etc.
while not clave2.isalpha():
clave2 = input('Clave segunda transposición: ').upper()
clave2 = clave2.replace(' ','')
clave2 = re.sub(r"([^n\u0300-\u036f]|n(?!\u0303(?![\u0300-\u036f])))[\u0300-\u036f]+",
r"\1", normalize("NFD", clave2), 0, re.I)
clave2 = normalize("NFC", clave2)
if clave2.isalpha():
print ("[+] Clave segunda transposición:", clave2)
else:
print ("*** ERROR: La clave para la segunda transposición sólo debe contener caracteres alfabéticos.")
elif misma_clave == "S":
# Para la segunda transposición se utiliza la misma clave que en la primera.
print ("[+] Clave segunda transposición igual que para la primera:", clave1)
clave2 = clave1
else:
misma_clave = ""
criptograma = cifrar(criptograma, clave2)
print ("[+] Criptograma:", criptograma)
else:
print ("*** ERROR: La clave para la primera transposición sólo debe contener caracteres alfabéticos.")
else:
print ("*** ERROR: El texto en claro a cifrar sólo debe contener caracteres alfabéticos.")
elif opcion == "2":
print ("")
print ("--- DESCIFRAR:")
# Descifrar: Se introduce el criptograma. Se convierten los caracteres a mayúsculas y
# se eliminan de él los espacios, las tildes, diéresis, etc.
criptograma = clave1 = clave2 = "*"
while not criptograma.isalpha():
criptograma = input('Criptograma a descifrar: ').upper()
criptograma = criptograma.replace(' ','')
criptograma = re.sub(r"([^n\u0300-\u036f]|n(?!\u0303(?![\u0300-\u036f])))[\u0300-\u036f]+",
r"\1", normalize("NFD", criptograma), 0, re.I)
criptograma = normalize("NFC", criptograma)
if criptograma.isalpha():
print ("[+] Criptograma a descifrar:", criptograma)
# Se introduce la clave empleada en el cifrado para la segunda transposición. Se convierten los caracteres a mayúsculas y
# se eliminan de ella los espacios, las tildes, diéresis, etc.
while not clave2.isalpha():
clave2 = input('Clave empleada en el cifrado para la segunda transposición: ').upper()
clave2 = clave2.replace(' ','')
clave2 = re.sub(r"([^n\u0300-\u036f]|n(?!\u0303(?![\u0300-\u036f])))[\u0300-\u036f]+",
r"\1", normalize("NFD", clave2), 0, re.I)
clave2 = normalize("NFC", clave2)
if clave2.isalpha():
print ("[+] Clave empleada en el cifrado para la segunda transposición:", clave2)
texto_claro = descifrar(criptograma, clave2)
misma_clave = ""
while misma_clave !="S" and misma_clave !="N":
misma_clave = input('¿La clave que se utilizó en el cifrado para la segunda transposición fue la misma que para la primera (S/N)?: ').upper()
if misma_clave == "N":
# Se introduce la clave que se empleó en el cifrado para la primera transposición. Se convierten los caracteres a mayúsculas y
# se eliminan de ella los espacios, las tildes, diéresis, etc.
while not clave1.isalpha():
clave1 = input('Clave empleada en el cifrado para la primera transposición: ').upper()
clave1 = clave1.replace(' ','')
clave1 = re.sub(r"([^n\u0300-\u036f]|n(?!\u0303(?![\u0300-\u036f])))[\u0300-\u036f]+",
r"\1", normalize("NFD", clave1), 0, re.I)
clave1 = normalize("NFC", clave1)
if clave1.isalpha():
print ("[+] Clave empleada en el cifrado para la primera transposición:", clave1)
else:
print ("*** ERROR: La clave empleada en la primera transposición sólo debe contener caracteres alfabéticos.")
elif misma_clave == "S":
# En el cifrado se utilizó la misma clave para la segunda transposición que para la primera.
print ("[+] En el cifrado se utilizó la misma clave para la segunda transposición que para la primera:", clave2)
clave1 = clave2
else:
misma_clave = ""
texto_claro = descifrar(texto_claro, clave1)
print ("[+] Texto en claro::", texto_claro)
else:
print ("*** ERROR: La clave para la segunda transposición sólo debe contener caracteres alfabéticos.")
else:
print ("*** ERROR: El criptograma a descifrar sólo debe contener caracteres alfabéticos.")
elif opcion == "3":
print ("*** FIN ******************************************")
salir = True
else:
print ("*** ERROR: Opción no válida.")
if __name__ == '__main__':
main()
Lo ejecuto:
- Cifrar:
- Descifrar:
Comentarios
Publicar un comentario