Criptografia: Cifra de substituição simples em Python

Depois de uma breve explicação sobre a classificação das cifras, vamos alterar uma das cifras utilizadas no blog. Já falamos da cifra de César. E, como sabemos, o algoritmo da cifra consiste na substituição de uma letra do alfabeto por sua correspondente seguindo o deslocamento indicado por uma chave numérica. No caso específico de César a chave era o número 3, mas podemos utilizar qualquer número entre 1 e 25 (pois nosso alfabeto é composto por 26 letras🙂 ).

Mas, se no lugar da chave numérica, usarmos uma chave composta por uma palavra? Com isso poderíamos criar um alfabeto de cifragem ou alfabeto cifrado próprio. Assim, transformamos a cifra de César em uma cifra de substituição simples. Por exemplo, se a palavra chave fosse CAVALARIA:

alfabeto normal  - |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|
alfabeto cifrado - |C|A|V|L|R|I|J|K|M|N|O|P|Q|S|T|U|W|X|Y|Z|B|D|E|F|G|H|

Observe que as letras repetidas são excluídas (CAVALARIA fica CAVLRI) e são colocadas no início do alfabeto de cifragem; e o restante do alfabeto cifrado é completado iniciando-se a partir da última letra da palavra chave (em nosso caso a letra J). Assim, a frase ‘atacaremos ao amanhecer’, fica: CZCVCXRQTYCTCQCSKRVRX.

CÓDIGO

class SimpleSubstitution:
	def __init__(self):
		self.p_alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
		self.decrypting = False

	def cipher_alphabet(self, password):
		''' (str) -> str
		Retorna um alfabeto cifrado iniciado com
		o texto da palavra chave password
		'''
		c_alphabet = []
		password = password.upper()
		for ch in password:
			if ch not in c_alphabet:
				c_alphabet.append(ch)
				idx = self.p_alphabet.find(ch)
		p_alphabet = self.p_alphabet[idx:] + self.p_alphabet[:idx]
		for ch in p_alphabet:
			if ch not in c_alphabet:
				c_alphabet.append(ch)
		return ''.join(c_alphabet)

	def encrypt(self, plaintext, password):
		'''(str, str) -> str
		Retorna o texto plano cifrado com a cifra de
		substituicao com a palavra chave password
		'''
		txt = ''
		p_alphabet = self.p_alphabet
		text = plaintext.replace(' ', '').upper()
		cipher = self.cipher_alphabet(password)
		if self.decrypting:
			p_alphabet, cipher = cipher, p_alphabet
			self.decrypting = False
		for ch in text:
			txt += cipher[p_alphabet.find(ch)]
		return txt

	def decrypt(self, ciphertext,  password):
		'''(str, str) -> str
		Retorna o texto cifrado decifrado com a cifra de
		substituicao com a palavra chave password
		'''
		self.decrypting = True
		return self.encrypt(ciphertext, password)

BitBin

Esta classe não trata caracteres acentuados e despreza os espaços em branco.

TESTES

O código foi salvo no arquivo simple_substitution.py

>>> import simple_substitution
>>> SimpleSubstitution().encrypt('O treinamento ocorrera no periodo da manha', 'cavalaria')
'TZXRMSCQRSZTTVTXXRXCSTURXMTLTLCQCSKC'
>>> SimpleSubstitution().decrypt('TZXRMSCQRSZTTVTXXRXCSTURXMTLTLCQCSKC', 'cavalaria')
'OTREINAMENTOOCORRERANOPERIODODAMANHA'

Sobre Fábio Medeiros

Meu nome é Fábio Medeiros. Cearense de nascença e com muito orgulho (daí o nome do blog, uma referência à minha terra). Sou formado em Tecnologia em Telemática, pelo CEFET-CE. Escrevi alguns artigos sobre programação JavaME e dispositivos portáteis (PDA) para a revista WebMobile.
Esse post foi publicado em Criptografia e marcado , . Guardar link permanente.

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s