El método de descifrado

El método de descifrado es muy semejante al anterior. El único cambio significativo (además de usar otros nombres de variables) es que ahora la clave se resta, no se suma. La clase quedaría así:

class CifradorCesar:
    
    import string
    alfabeto = string.printable
    
    def __init__(self, clave):
        self.clave = clave
        
    def cifra(self, mensaje):
        mensaje_cifrado = ""
        for letra in mensaje:
            indice = CifradorCesar.alfabeto.index(letra) 
            nuevo_indice = (indice + self.clave) % len(CifradorCesar.alfabeto)
            mensaje_cifrado += CifradorCesar.alfabeto[nuevo_indice]
        return mensaje_cifrado
    
    def descifra(self, mensaje_cifrado):
        mensaje = ""
        for letra_cifrada in mensaje_cifrado:
            indice = CifradorCesar.alfabeto.index(letra_cifrada)
            nuevo_indice = (indice - self.clave) % len(CifradorCesar.alfabeto)
            mensaje += CifradorCesar.alfabeto[nuevo_indice]
        return mensaje

Para probar la clase, vamos a cifrar un texto y a descifrarlo a continuación (¡debería devolver el texto inicial!). Comenzamos instanciando la clase:

c = CifradorCesar(7)

m = c.cifra("Python para Data Science")
m

'WFAovu1whyh1KhAh1Zjplujl'

c.descifra(m)

'Python para Data Science'

Y funciona también...