#!/usr/bin/python
# -*- coding: utf-8 -*-
# Algoritmo Cifrado de Hill en 26 caracteres.
# Funciona perfectamente. IMPORTANTISIMO LO DEL -coding utf-8- y las matrices en mod26 y mod27
# INTRODUCIMOS EN UNA LISTA EL NUMERO DE CARACTERES A UTILIZAR
v2 = ["00 ", "01 ", "02 ", "03 ", "04 ", "05 ", "06 ", "07 ", "08 ", "09 ", "10 ", "11 ", "12 ", "13 ", "14 ", "15 ", "16 ", "17 ", "18 ", "19 ", "20 ", "21 ", "22 ", "23 ", "24 ", "25 "] # 26 caracteres que conforman el alfabeto ya que -00- se cuenta como caracter.
# INTRODUCIMOS LOS CARACTERES POR LOS QUE VAN A SER SUSTITUIDOS
v1 = ["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"] # 26 caracteres.
print
# FUNCION QUE CONVIERTE LAS LETRAS EN NUMEROS DEL -O- AL -25-.
def crypt(text): # FUNCION QUE CODIFICA EL TEXTO PLANO
texto = text
salir = False
v3 = 0
while v3 <= 25: # MODIFICAMOS SEGUN LOS VALORES DE v1 Y v2 PARA ENTRAR EN RANGO. LO CORRECTO AQUI ES 25 YA QUE EL LIMITE DE v2 ES 25.
text = text.replace(v1[v3], v2[v3]) # REEMPLAZAMOS UNOS CARACTERES POR OTROS.
v3 = v3 + 1 # CONTADOR
# print text # ESTA LINEA IMPRIME POR PANTALLA EL RESULTADO DETALLADO. LA PODEMOS QUITAR.
print "EL TEXTO CONVERTIDO EN NUMEROS DEL -0- AL -25- ES: ", text # ESTA IMPRIME EL RESULTADO FINAL.
crypt(raw_input("INTRODUCE TEXTO PLANO -MENSAJE- A CONVERTIR EN NUMEROS DEL -0- AL -25-: "))
print
# YA TENEMOS NUESTRO TEXTO PLANO PASADO A NUMEROS DEL 0 AL 25.
# AHORA CREAMOS LAS LISTAS QUE CONTENDRA LA MATRIZ Y LAS MATRICES EN SI. CODIFICACION Y TEXTO.
# CREAMOS MATRIZ -K- QUE DEBE SER INVERTIBLE, ES DECIR, determinante distinto de 0 y m.c.d. (det, mod) = 1.
matriz1 = []
filas = int(raw_input("Inserta FILAS de Matriz de codificacion: "))
columnas = int(raw_input("Inserta COLUMNAS de Matriz de codificacion: "))
for i in range(filas):
matriz1.append([0]*columnas)
for f in range(filas):
for c in range(columnas):
matriz1[f][c] = int(raw_input("Elemento f%d, c%d : " % (f,c)))
print matriz1 # IMPRIMIMOS MATRIZ 1 o MATRIZ DE CODIFICACION
for elemento in matriz1: # IMPRIMIMOS EN FORMA DE MATRIZ
print elemento
print
# CREAMOS MATRIZ 2 QUE SERA EL TEXTO PASADO A NUMEROS ENTRE 0 Y 25
matriz2 = [] # ESTA MATRIZ NO GENERA UNA OPERACION AUTENTICA DE MATRIZ, SOLO MULTIPLICA FILAS.
filas = int(raw_input("Inserta FILAS de Matriz 2 -texto- : "))
columnas = int(raw_input("Inserta COLUMNAS de Matriz 2 -texto- : "))
for i in range(filas):
matriz2.append([0]*columnas)
for f in range(filas):
for c in range(columnas):
matriz2[f][c] = int(raw_input("Elemento %d, %d : " % (f,c))) # POR ESO AQUI NO PONEMOS FILAS Y COLUMNAS.
print matriz2 # IMPRIMIMOS MATRIZ 2
for elemento in matriz2: # IMPRIMIMOS EN FORMA DE MATRIZ
print elemento
print
# CREAMOS LA ESTRUCTURA DE LA MATRIZ RESULTADO
matrizresultado = []
filas = int(raw_input("Inserta FILAS de la Matriz Resultado: "))
columnas = int(raw_input("Inserta COLUMNAS de la Matriz Resultado: "))
for i in range(filas):
matrizresultado.append([0]*columnas)
for f in range(filas):
for c in range(columnas):
# matrizresultado[f][c] = int(raw_input("Elemento f%d, c%d : " % (f,c)))
matrizresultado[f][c] = 0 # LA MATRIZ RESULTADO DEBE SER UNA MATRIZ VACIA
print matrizresultado # IMPRIMIMOS LA FORMA DE LA MATRIZ RESULTADO
for elemento in matrizresultado: # IMPRIMIMOS LA MATRIZ RESULTADO EN FORMA DE MATRIZ
print elemento
print
# AQUI VIENE EL PROCESO DE MULTIPLICACION DE FILAS Y COLUMNAS, QUE COMO HEMOS DICHO, NO ES MUY CORRECTO.
a=3 # int(raw_input("Inserta -COLUMNAS- matriz de codificacion: ")) # METEMOS EL NUMERO DE FILAS Y COLUMNAS PARA NO LIMITARLO A 3
b=int(raw_input("Inserta -COLUMNAS- matriz de texto: ")) # EJEM: PARA MATRIZ 3 x 1 => a=3 b=1 r=3
r=3 # int(raw_input("Inserta -FILAS- matriz resultado: ")) # EJEM: PARA MATRIZ 3 x 2 => a=3 b=2 r=3
# EJEM: PARA MATRIZ 3 x 3 => a=3 b=3 r=3
# EJEM: PARA MATRIZ 3 x 4 => a=3 b=4 r=3
#for x in range(0,3):
for x in range(0,a):
# for y in range(0,3):
for y in range(0,b):
# for z in range(0,3):
for z in range(0,r):
matrizresultado[x][y]+=matriz1[x][z]*matriz2[z][y]
print matrizresultado
for elemento in matrizresultado:
print elemento
print
# AHORA TRATAMOS DE APLANAR LA LISTA DE LISTAS Y PASARLO A mod26.
def flattener(lst): # DEFINIMOS LA FUNCION QUE NOS APLANARA LA LISTA
return [item for sublist in lst for item in sublist]
#lista = [[36, 60, 41],[25, 55, 46]] ejemplo de como queda
print flattener(matrizresultado) # IMPRIMIMOS LAS LISTAS EN UNA SOLA LISTA.
#[36, 60, 41, 25, 55, 46] ejemplo de como queda
for elemento in flattener(matrizresultado): # IMPRIMIMOS EL RESULTADO EN mod 26
print elemento%26, # LA , ES PARA IMPRIMIR HORIZONTAL. (mod26)
print
# UNA VEZ OBTENIDO EL RESULTADO DE LA MULTIPLICACION DE MATRICES, PASAMOS A LA CONVERSION DE LOS NUMEROS EN TEXTO.
# INTRODUCIMOS LA LISTA DE NUMEROS A UTILIZAR
v1 = ["00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25"] # 26 caracteres que conforman el alfabeto ya que el -00- cuenta como caracter.
# INTRODUCIMOS LOS CARACTERES POR LOS QUE VAN A SER SUSTITUIDOS
v2 = ["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"] # 26 caracteres.
print
# FUNCION QUE NOS CONVERTIRA LAS CIFRAS OBTENIDAS EN mod26 EN LETRAS DEL ALFABETO.
def crypt(text): # FUNCION QUE CODIFICA EL TEXTO PLANO
texto = text
salir = False
v3 = 0
while v3 <= 25: # MODIFICAMOS SEGUN LOS VALORES DE v1 Y v2 PARA ENTRAR EN RANGO. LO CORRECTO ES 25.
text = text.replace(v1[v3], v2[v3]) # REEMPLAZAMOS UNOS CARACTERES POR OTROS.
v3 = v3 + 1 # CONTADOR
# print text # ESTA LINEA IMPRIME POR PANTALLA EL RESULTADO DETALLADO. LA PODEMOS QUITAR.
print "Y POR FIN, EL TEXTO FINAL ES: ", text # ESTA IMPRIME EL RESULTADO FINAL.
crypt(raw_input("PASO FINAL.- Introduce los GUARISMOS de dos en dos para convertir en TEXTO PLANO: "))
print