Cifrado de Hill en Python

#!/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