Criptografia: Cifra ou disco de Alberti em Python

Leon Battista Alberti foi um autor, artista, arquiteto, poeta, sacerdote, linguista, filósofo e criptógrafo italiano que descreveu em um tratado (De Componendis Cifris ou De Cifris, 1466), uma técnica criptográfica que fazia uso de dois discos (um fixo e outro móvel) para cifrar e decifrar mensagens.

Como dito, os discos de Alberti são compostos por dois discos: um fixo e outro móvel. No disco fixo fica o alfabeto plano e no disco móvel fica o alfabeto cifrado. Alberti descreve dois métodos para cifragem/decifragem com os discos.

Disco de Alberti

Disco de Alberti

Para melhor exemplificar utilizaremos o disco da imagem acima, onde o disco fixo é o mais externo (com os caracteres maiúsculos) e o disco móvel é o disco interno (com os caracteres minúsculos).

Primeiro Método

Neste primeiro método escolhe-se um caracter do disco móvel que será utilizado como chave, por exemplo, a letra k. A cifragem se dá adicionando-se letras maiúsculas à mensagem a ser cifrada. Quando o usuário encontrar uma letra maiúscula no texto, a chave do disco móvel deve ser movida até que esta fique embaixo da letra maiúscula da mensagem. Agora, as demais letras são cifradas com as letras correspondentes ao disco móvel. Encontrando-se outra letra maiúscula, o disco móvel é deslocado até que a chave k fique abaixo da letra maiúscula no alfabeto plano e continua-se cifrando assim, até a mensagem acabar.

Como exemplo, vamos cifrar a mensagem ‘O sargento é o traidor’. Primeiro, todas as letras maiúsculas são convertidas em minúsculas, os espaços em branco são removidos e os caracteres especiais são trocados. Assim, a mensagem ficará ‘osargentoeotraidor’. Escolhemos a chave, neste caso a letra k, e qual será a letra inicial que será relacionada à chave. Para facilitar, escolhemos a letra B, como mostrado na imagem. Assim, a nossa mensagem deve começar com a letra B, ‘Bosargentoeotraidor’. Se adicionarmos outras letras maiúsculas na mensagem, o disco móvel deverá ser deslocado até que a chave, k, corresponda àquela letra. A mensagem final ficará assim: ‘BosargentoPeoStraidor’. Para cifrar checamos a letra minúscula da mensagem no disco fixo (com letras maiúsculas) e vemos qual é a letra correspondente no disco móvel (letras minúsculas). Abaixo um passo a passo:

Primeira iteração k -> B

DISCOS
FIXO  - A B C D E F G I L M N O P Q R S T V X Z 1 2 3 4
MÓVEL - g k l n p r t v z & x y s o m q i h f d b a c e

texto plano   - B o s a r g e n t o P e o S t r a i d o r
texto cifrado - B y q g m t p x i y P

Segunda iteração k -> P

DISCOS
FIXO  - A B C D E F G I L M N O P Q R S T V X Z 1 2 3 4
MÓVEL - o m q i h f d b a c e g k l n p r t v z & x y s

texto plano   - B o s a r g e n t o P e o S t r a i d o r
texto cifrado - B y q g m t p x i y P h g S

Terceira iteração k -> S

DISCOS
FIXO  - A B C D E F G I L M N O P Q R S T V X Z 1 2 3 4
MÓVEL - x y s o m q i h f d b a c e g k l n p r t v z &

texto plano   - B o s a r g e n t o P e o S t r a i d o r
texto cifrado - B y q g m t p x i y P h g S l g x h o a g

Nossa mensagem cifrada será ByqgmtpxiyPhgSlgxhoag.

Segundo Método

O segundo método muda um pouco, pois ao invés de se usar letras, usam-se os números que existem no disco fixo. Desta vez escolhe-se como chave um caracter do disco fixo como índice e uma letra do alfabeto cifrado para posição inicial. Ao se encontrar um número na mensagem a ser cifrada, a letra do disco móvel correspondente ao número no disco fixo é movida até corresponder com a letra escolhida como índice no disco fixo. E a cifragem continua assim até o fim da mensagem. Vamos utilizar a mesma mensagem do primeiro método: ‘O sargento é o traidor’. Trocamos todos os caracteres maiúsculos por minúsculos, removemos os caracteres em branco e trocamos os caracteres especiais. No final ficamos com a mensagem ‘osargentoeotraidor’.

Escolheremos a letra D no disco fixo como índice e a letra p no disco móvel como caracter inicial de cifragem. Adicionaremos alguns números (entre 1 e 4) e os inseriremos nos locais que desejarmos na mensagem a ser cifrada. A mensagem final será ‘Dosar1gento4eotra2idor’. Abaixo o passo a passo para cifragem:

Primeira iteração p -> D

DISCOS
FIXO  - A B C D E F G I L M N O P Q R S T V X Z 1 2 3 4
MÓVEL - k l n p r t v z & x y s o m q i h f d b a c e g

texto plano   - D o s a r 1 g e n t o 4 e o t r a 2 i d o r
texto cifrado - D s i k q 1

Segunda iteração 1 (a) -> D

DISCOS
FIXO  - A B C D E F G I L M N O P Q R S T V X Z 1 2 3 4
MÓVEL - f d b a c e g k l n p r t v z & x y s o m q i h

texto plano   - D o s a r 1 g e n t o 4 e o t r a 2 i d o r
texto cifrado - D s i k q 1 g c p x r 4

Terceira iteração 4 (h) -> D

DISCOS
FIXO  - A B C D E F G I L M N O P Q R S T V X Z 1 2 3 4
MÓVEL - m q i h f d b a c e g k l n p r t v z & x y s o

texto plano   - D o s a r 1 g e n t o 4 e o t r a 2 i d o r
texto cifrado - D s i k q 1 g c p x r 4 f k t p m 2

Quarta iteração 2 (y) -> D

DISCOS
FIXO  - A B C D E F G I L M N O P Q R S T V X Z 1 2 3 4
MÓVEL - z & x y s o m q i h f d b a c e g k l n p r t v

texto plano   - D o s a r 1 g e n t o 4 e o t r a 2 i d o r
texto cifrado - D s i k q 1 g c p x r 4 f k t p m 2 q y d c

Assim, a mensagem cifrada será Dsikq1gcpxr4fktpm2qydc.

Terceiro Método

Afora os dois métodos citados por Alberti, podemos criar um outro método que utilizaria um sistema de deslocamento automático sem que precisemos inserir outros caracteres na mensagem, bastaria somente escolher a letra inicial do disco fixo, a letra inicial do disco móvel e um número de deslocamento automático. Este número de deslocamento indicaria quantas casas o disco móvel seria deslocado, para a direita ou esquerda, a cada cifragem de um caracter. Para facilitar vamos utilizar uma mensagem menor : ‘perigo’. Escolhemos a letra O do disco fixo, a letra c do disco móvel e o número 2 como chave de deslocamento.

Primeiro caracter (p)

DISCOS
FIXO  - A B C D E F G I L M N O P Q R S T V X Z 1 2 3 4
MÓVEL - y s o m q i h f d b a c e g k l n p r t v z & x

texto plano   - p e r i g o
texto cifrado - e

Segundo caracter (e)

DISCOS
FIXO  - A B C D E F G I L M N O P Q R S T V X Z 1 2 3 4
MÓVEL - & x y s o m q i h f d b a c e g k l n p r t v z

texto plano   - p e r i g o
texto cifrado - e o

Terceiro caracter (r)

DISCOS
FIXO  - A B C D E F G I L M N O P Q R S T V X Z 1 2 3 4
MÓVEL - v z & x y s o m q i h f d b a c e g k l n p r t

texto plano   - p e r i g o
texto cifrado - e o a

Quarto caracter (i)

DISCOS
FIXO  - A B C D E F G I L M N O P Q R S T V X Z 1 2 3 4
MÓVEL - r t v z & x y s o m q i h f d b a c e g k l n p

texto plano   - p e r i g o
texto cifrado - e o a s

Quinto caracter (g)

DISCOS
FIXO  - A B C D E F G I L M N O P Q R S T V X Z 1 2 3 4
MÓVEL - n p r t v z & x y s o m q i h f d b a c e g k l

texto plano   - p e r i g o
texto cifrado - e o a s &

Sexto caracter (o)

DISCOS
FIXO  - A B C D E F G I L M N O P Q R S T V X Z 1 2 3 4
MÓVEL - k l n p r t v z & x y s o m q i h f d b a c e g

texto plano   - p e r i g o
texto cifrado - e o a s & s

A mensagem cifrada será eoas&s.

CÓDIGO

Abaixo o código da classe que implementa os três métodos acima descritos e também com funções que nos permitem adicionar alfabetos personalizados e de tamanho variado, não nos limitando ao alfabeto do disco da imagem no início do post. O código foi salvo no arquivo alberti.py.

class Alberti:
	def shift(self, shift):
		''' (int) -> None
		Desloca o disco movel a quantidade de elementos em shift.
		'''
		shift = -shift
		self.movable_disk = self.movable_disk[shift:] + self.movable_disk[:shift]

	def set_fixed_disk(self, plain_alphabet):
		''' (str) -> None
		Configura o alfabeto do disco fixo com o texto de plain_alphabet.
		'''
		self.fixed_disk = plain_alphabet.upper()

	def set_movable_disk(self, cipher_alphabet):
		''' (str) -> None
		Configura o alfabeto do disco movel com o texto de cipher_alphabet.
		'''
		self.movable_disk = cipher_alphabet.lower()

	def set_keys(self, fixed_key, movable_key):
		''' (char, charstr) -> None
		Configura as chaves do disco fixo e do disco movel;
		Desloca o disco movel de acordo com as chaves.
		'''
		self.set_fixed_key(fixed_key)
		self.set_movable_key(movable_key)
		fixed_id = self.fixed_disk.find(self.fixed_key)
		movable_id = self.movable_disk.find(self.movable_key)
		shift = fixed_id - movable_id
		self.shift(shift)

	def encrypt(self, plaintext, shift = 0, decrypt = False):
		''' (str, [int], [bool]) -> str
		Cifra o plaintext com a cifra de Alberti.
		'''
		ciphertext = ''
		for ch in plaintext:
			if ch.isupper():
				#letra maiuscula
				self.set_keys(ch, self.movable_key)
			elif ch.isdigit():
				#numero
				movable_key = self.movable_disk[self.fixed_disk.find(ch)]
				self.set_keys(self.fixed_key, movable_key)
			else:
				#letra minuscula
				if decrypt:
					#decifrando
					i = self.movable_disk.find(ch)
					ch = self.fixed_disk[i].lower()
				else:
					#cifrando
					i = self.fixed_disk.find(ch.upper())
					ch = self.movable_disk[i]
				if shift:
					#deslocamento
					self.shift(shift)
			ciphertext += ch
		return ciphertext

	def decrypt(self, ciphertext, shift = 0):
		''' (str, [int]) -> str
		Decifra utilizando a cifra de Alberti.
		'''
		#return self.encrypt(ciphertext, shift, True)
		text = ''
		plaintext = self.encrypt(ciphertext, shift, True)
		for ch in plaintext:
			if ch.islower():
				text += ch
		return text

	def set_fixed_key(self, fixed_key):
		''' (char) -> None
		Configura a chave do disco fixo.
		'''
		self.fixed_key = fixed_key.upper()

	def set_movable_key(self, movable_key):
		''' (char) -> None
		Configura a chave do disco movel.
		'''
		self.movable_key = movable_key.lower()

BitBin

TESTES

Desta feita, não vou mostrar o uso da classe, mas vou criar um arquivo de teste e importar a classe Alberti para ele e executar a cifragem/decifragem dos exemplos citados no post. Este código teste foi salvo no arquivo alberti_teste.py e deve ser salvo no mesmo diretório do arquivo alberti.py.

from alberti import Alberti
alb = Alberti()

## PRIMEIRO METODO
##alfabeto do disco fixo
alb.set_fixed_disk('ABCDEFGILMNOPQRSTVXZ1234')
##alfabeto do disco movel
alb.set_movable_disk('gklnprtvz&xysomqihfdbace')
##chave do disco movel
alb.set_movable_key('k')
cifrado = alb.encrypt('BosargentoPeoStraidor')
print 'Cifrando/Decifrando com o primeiro metodo da cifra de Alberti'
print 'Texto cifrado - ' + cifrado
print 'Texto decifrado - ' + alb.decrypt(cifrado)
print ''

## SEGUNDO METODO
##chave inicial do disco movel
alb.set_movable_key('p')
print 'Cifrando/Decifrando com o segundo metodo da cifra de Alberti'
cifrado = alb.encrypt('Dosar1gento4eotra2idor')
print 'Texto cifrado - ' + cifrado
##chave inicial do disco movel
alb.set_movable_key('p')
print 'Texto decifrado - ' + alb.decrypt(cifrado)
print ''

## TERCEIRO METODO
print 'Cifrando/Decifrando com o terceiro metodo'
##chaves do disco fixo e do disco movel
alb.set_keys('O', 'c')
cifrado = alb.encrypt('perigo', 2)
print 'Texto cifrado - ' + cifrado
alb.set_keys('O', 'c')
print 'Texto decifrado - ' + alb.decrypt(cifrado, 2)

O arquivo acima, sendo executado, tem como saída o resultado abaixo:

Cifrando/Decifrando com o primeiro metodo da cifra de Alberti
Texto cifrado - ByqgmtpxiyPhgSlgxhoag
Texto decifrado - osargentoeotraidor</code>

Cifrando/Decifrando com o segundo metodo da cifra de Alberti
Texto cifrado - Dsikq1gcpxr4fktpm2qydc
Texto decifrado - osargentoeotraidor

Cifrando/Decifrando com o terceiro metodo
Texto cifrado - eoas&amp;s
Texto decifrado - perigo

Fontes:
http://en.wikipedia.org/wiki/Alberti_cipher_disk
http://en.wikipedia.org/wiki/Alberti_cipher
http://www.numaboa.com.br/criptografia/historia/158-alberti
http://www.numaboa.com.br/criptografia/127-substituicao-polialfabetica/164-alberti

Publicado em Criptografia | Marcado com , , | Deixe um comentário

Criptografia: Cifra de Políbio ou Quadrado de Políbio em Python

A cifra de Políbio ou quadrado de Políbio, é um cifra de substituição relatada pelo historiador grego Políbio em seu livro Histórias, que trata da ascensão do Império Romano.

Seu princípio de funcionamento consiste numa tabela quadrada (mesmo número de linhas e colunas :) ), onde os caracteres são disponibilizados um em cada célula desta tabela. Políbio utilizava um quadrado de 5×5, ou seja, 25 células e utilizava o alfabeto grego de 24 caracteres. A última célula era preenchida com um sinal para sincronização.

Trazendo para nossos dias, utilizamos o mesmo quadrado de 5×5 e o alfabeto latino de 26 letras. Como há uma letra a mais, nos utilizaremos de um artifício em unir duas letras numa mesma célula. Em alguns sites, com conteúdo em inglês, costuma-se unir as letras i e j numa mesma célula, ficando o quadrado como demonstrado abaixo:

    1   2   3    4    5
1 | a | b | c |  d  | e |
2 | f | g | h | i/j | k |
3 | l | m | n |  o  | p |
4 | q | r | s |  t  | u |
5 | v | w | x |  y  | z |

O processo de cifragem se dá pela troca da letra do alfabeto normal pelo número da linha seguido pelo número da coluna, por exemplo, a letra a ficará 11, a b, 12 e assim por diante. Assim, a palavra guerra, cifrada, ficará: 22 45 15 42 42 11 ou 224515424211. O processo de decifragem é o inverso: pega-se o número da linha e da coluna e substitui-se pela letra correspondente na célula.

Por exemplo, o código 24 34 22 34 43 14 15 22 45 15 42 42 11, decifrado, fica iogosdeguerra (note que a palavra iogos deveria ser jogos, mas, como comprimimos as letras i e j na mesma célula, na decifragem utilizamos somente uma delas, neste caso, a letra i. E como as partes envolvidas na comunicação sabem deste detalhe, fica fácil para alternar entre as duas letras).

Uma outra forma de utilizar o quadrado de Políbio é expandi-lo para a utilização das letras do alfabeto e os numerais de 0 a 9. Assim, nosso quadrado para a ser de 6×6, ficando como mostrado abaixo:

    1   2   3   4   5   6
1 | a | b | c | d | e | f |
2 | g | h | i | j | k | l |
3 | m | n | o | p | q | r |
4 | s | t | u | v | w | x |
5 | y | z | 0 | 1 | 2 | 3 |
6 | 4 | 5 | 6 | 7 | 8 | 9 |

Desta forma, não precisamos ter dois caracteres numa mesma célula. Utilizando este quadrado a frase A senha de acesso ao sistema é 1945, cifrada, fica (lembrando que desconsiderei os espaços em branco e caracteres especiais): 11 41 15 32 22 11 14 15 11 13 15 41 41 33 11 33 41 23 41 42 15 31 11 15 54 66 61 62.

Para dificultar um pouco mais o trabalho de quem tenta decifrar nossa mensagem ultra-secreta :) , há a possibilidade de se utilizar uma palavra-chave com a cifra de Políbio. Se utilizarmos a palavra-chave cavalaria, nosso quadrado ficará como mostrado abaixo:

    1   2   3   4   5   6
1 | c | a | v | l | r | i |
2 | j | k | m | n | o | p |
3 | q | s | t | u | w | x |
4 | y | z | 0 | 1 | 2 | 3 |
5 | 4 | 5 | 6 | 7 | 8 | 9 |
6 | b | d | e | f | g | h |

Utilizamos o mesmo conceito aplicado na cifra de substituição simples. As letras repetidas da palavra chave são removidas, cavalaria fica cavlri, e preenchemos as demais células com as letras restantes do alfabeto, seguidas dos numerais de 0 a 9.

E, a mesma frase, A senha de acesso ao sistema é 1945, cifrada, fica: 12 32 63 24 66 12 62 63 12 11 63 32 32 25 12 25 32 16 32 33 63 23 12 63 44 56 51 52.

CÓDIGO

O código foi salvo no arquivo Polybius.py. Lembrando que caracteres especiais não são tratados e os espaços em branco são descartados.

class Polybius:
    def __init__(self):
        ## p_alphabet nao possui a letra j, que sera substituida
        ## pela letra i na cifragem e decifragem
        self.p_alphabet = 'abcdefghiklmnopqrstuvwxyz'
        self.p_alphanum = 'abcdefghijklmnopqrstuvwxyz0123456789'

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

    def create_square(self, alphabet, lines):
        ''' (list, int) -> list of str
        Retorna uma tabela lista quadrada definida por lines
        com cada celula preenchida com um caracter de alphabet
        '''
        square = []
        temp = []
        count = 0
        for ch in alphabet:
            temp.append(ch)
            count += 1
            if count == lines:
                square.append(temp)
                temp = []
                count = 0
        return square

    def select_square(self, key):
        ''' (int) -> list of str
        Retorna o quadrado de Polibio referente a key utilizada.
        Se key for True, usa-se o quadrado de Polibio com letras e numerais;
        Se key for uma string, retorna o quadrado de Polibio com key como palavra chave.
        Se nao houver key, usa-se o quadrado de Polibio padrao.
        '''
        if key:
            if key == True:
                return self.create_square(self.p_alphanum, 6)
            else:
                return self.create_square(self.cipher_alphabet(str(key)), 6)
        return self.create_square(self.p_alphabet, 5)

    def encrypt(self, plaintext, key = None):
        ''' (str, str) -> str
        Retorna o plaintext cifrado com a cifra de Polibio.
        Se key = True, cifra com quadrado de Polibio com letras e numeros.
        Se key = uma string, cifra o quadrado de Polibio com key como palavra chave.
        Se nao houver key, cifra com o quadrado de polibio padrao.
        '''
        square = self.select_square(key)
        ciphertext = ''
        for ch in plaintext.lower():
            idx = 1
            if ch == 'j':
                ch = 'i'
            for linha in square:
                if ch in linha:
                    ciphertext += str(idx) + str(linha.index(ch) + 1) + ' '
                idx += 1
        return ciphertext

    def decrypt(self, ciphertext, key = None):
        ''' (str, str) -> str
        Retorna o ciphertext decifrado com a cifra de Polibio.
        Se key = True, decifra com quadrado de Polibio com letras e numeros.
        Se key = uma string, decifra o quadrado de Polibio com key como palavra chave.
        Se nao houver key, decifra com o quadrado de polibio padrao.
        '''
        square = self.select_square(key)
        plaintext = ''
        ciphertext = str(ciphertext).replace(' ', '')
        for num in range(0, len(ciphertext), 2):
            var = int(ciphertext[num:num + 2])
            i, j = var / 10, var % 10
            if i - 1 < len(square) and j - i < len(square[0]):
                plaintext += square[i - 1][j - 1]
        return plaintext.lower()

BitBin

TESTES

>>> from polybius import Polybius
>>> Polybius().encrypt('jogos de guerra')
'24 34 22 34 43 14 15 22 45 15 42 42 11 '
>>> Polybius().decrypt('24 34 22 34 43 14 15 22 45 15 42 42 11')
'iogosdeguerra'
>>> Polybius().decrypt(24342234431415224515424211)
'iogosdeguerra'
>>> Polybius().encrypt('Senha de acesso e 1986', True)
'41 15 32 22 11 14 15 11 13 15 41 41 33 15 54 66 65 63 '
>>> Polybius().decrypt('41 15 32 22 11 14 15 11 13 15 41 41 33 15 54 66 65 63', True)
'senhadeacessoe1986'
>>> Polybius().encrypt('Senha de acesso e 1986', 'cavalaria')
'32 63 24 66 12 62 63 12 11 63 32 32 25 63 44 56 55 53 '
>>> Polybius().decrypt('32 63 24 66 12 62 63 12 11 63 32 32 25 63 44 56 55 53',  'cavalaria')
'senhadeacessoe1986'

Fontes:

http://www.numaboa.com.br/criptografia/128-substituicao-tomografica/179-polibio

http://en.wikipedia.org/wiki/Polybius

Publicado em Criptografia | Marcado com , | Deixe um comentário

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'
Publicado em Criptografia | Marcado com , | Deixe um comentário

Correção dos módulos das Bíblias ACF e ACF 2007 para o e-Sword

Conforme relatado no comentário do Hiroshi, os módulos da ACF e da ACF 2007 estavam com os versículos 23 a 29 do capítulo 3 do livro de Daniel faltando.

Corrigi o erro e estou disponibilizando os módulos novamente. Ambos foram testados com o e-Sword 10.2.1.

Para instalar baixe os arquivo ACF.bblx ou ACF2007.bblx e copie-os para o diretório onde está instalado o e-Sword.

[ATUALIZAÇÃO 22/01/2014]

Conforme relatado no comentário do Jean, o livro de Hebreus, na ACF 1994, não estava aparecendo. Problema corrigido e novo arquivo disponibilizado.

[ATUALIZAÇÃO 28/11/2013]

Corrigido o problema da busca com palavras acentuadas. E, como crédito, o tamanho dos arquivos diminuiu. :) .

Publicado em Bíblia | Marcado com , , | 6 Comentários

Criptografia: cifras de transposição e cifras de substituição

Até o momento apresentamos quatro cifras diferentes. Mas elas podem ser classificadas de acordo com seu método de cifragem.

Cifras de Transposição

Uma cifra é caracterizada como cifra de transposição quando os caracteres do texto plano são trocados de posição entre si seguindo uma determinada regra (o algoritmo da cifra). Assim, as cifras rail fence (cerca de trilhos) e scytale espartano, caracterizam-se como cifras de transposição.

Cifras de Substituição

Uma cifra de substituição tem como característica a permanência do caracter do texto plano em sua posição original, mas o mesmo é substituído por outro caracter ou símbolo de um conjunto pré-escolhido, chamado de alfabeto de substituição ou alfabeto de cifra. Além de caracteres isolados, palavras ou até mesmo frases podem ser substituídas.

Existem algumas classificações para as cifras de substituição: monoalfabéticas ou simples, homófonas, polialfabéticas, poligrâmicas e poligráficas.

A substituição simples ou monoalfabética é aquela em que para cada caracter do texto plano corresponde um só caracter ou símbolo do alfabeto de substituição.

A substituição homófona possui um ou mais símbolos para alguns caracteres do alfabeto normal.

Já as cifras de substituição polialfabéticas são as que utilizam mais de um alfabeto de substituição para o alfabeto normal.

Por último, as cifras de substituição poligráficas substituem grupos de caracteres da mensagem por símbolos.

A cifra de César e as cifras hebraicas são exemplos de cifras de substituição simples.

Publicado em Criptografia | Marcado com , , , | 1 Comentário

Criptografia: cifras hebraicas (Atbash, Atbah e Albam) em Python

Você já leu a Bíblia? Não? Mas deve saber de que livro estou falando.

Se você já a leu, deve ter lido o livro do profeta Jeremias, certo?

Pois bem, neste livro, algumas palavras do texto foram cifradas utilizando a cifra Atbash.

O Atbash vem da grafia das letras hebraicas Aleph, Tav, Beth, Shin. O seu funcionamento é bem simples: a primeira letra do alfabeto é trocada pela última, a segunda letra pela penúltima e assim sucessivamente. Abaixo um resumo com os caracteres latinos do alfabeto português:

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

Como exemplo, a palavra biblia em Atbash fica: YRYORZ.

Há duas outras cifras hebraicas chamadas Atbah e Albam.

Seguindo o mesmo procedimento a cifra Atbah vem da grafia das letras hebraicas Aleph, Teth, Beth e Heth e a cifra Albam das letras  Aleph, Lamed, Beth e Mem.

Para cifrar com Albam, primeiro divide-se o alfabeto normal em duas metades. A segunda metade do alfabeto é colocada na frente da primeira metade e a cifragem se dá pela troca da primeira letra do alfabeto normal pela primeira letra deste alfabeto trocado; a segunda letra do alfabeto normal pela segunda do alfabeto trocado e assim por diante. A tabela abaixo demonstra isto melhor.

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

Então, a palavra biblia em Albam fica: OVOYVN.

Já a cifra Atbah segue uma sequência própria para a cifragem. Abaixo a tabela com a cifra.

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

A palavra biblia em Albam: HAHPAI.

CÓDIGO

Resolvi implementar as três cifras numa classe só e a chamei de hebrew.py. A classe descarta os espaços em branco e não trata caracteres especiais.

class HebrewCipher:
    atbash = 'ZYXWVUTSRQPONMLKJIHGFEDCBA'
    albam = 'NOPQRSTUVWXYZABCDEFGHIJKLM'
    atbah = 'IHGFNDCBARQPOEMLKJZYXWVUTS'

    def __init__(self):
        self.__plain = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'

    def encrypt(self, text, cipher):
        ''' (HebrewCipher, str, str) -> str
        Retorna o texto cifrado com
        a cifra hebraica escolhida
        '''

        txt = ''
        text = text.replace(' ', '').upper()
        for ch in text:
            idx = self.__plain.find(ch)
            txt += cipher[idx]
        return txt

    def decrypt(self, text, cipher):
        ''' (HebrewCipher, str, str) -> str
        Retorna o texto decifrado com
        a cifra hebraica escolhida
        '''
        return self.encrypt(text, cipher).lower()

BitBin

TESTES

>>> from hebrew import HebrewCipher
>>> HebrewCipher().encrypt('o livro cristao e a biblia', HebrewCipher.atbash)
'LOREILXIRHGZLVZYRYORZ'
>>> HebrewCipher().decrypt('LOREILXIRHGZLVZYRYORZ', HebrewCipher.atbash)
'olivrocristaoeabiblia'
>>> HebrewCipher().encrypt('o livro cristao e a biblia', HebrewCipher.albam)
'BYVIEBPEVFGNBRNOVOYVN'
>>> HebrewCipher().decrypt('BYVIEBPEVFGNBRNOVOYVN', HebrewCipher.albam)
'olivrocristaoeabiblia'
>>> HebrewCipher().encrypt('o livro cristao e a biblia', HebrewCipher.atbah)
'MPAWJMGJAZYIMNIHAHPAI'
>>> HebrewCipher().decrypt('MPAWJMGJAZYIMNIHAHPAI', HebrewCipher.atbah)
'olivrocristaoeabiblia'

Fontes:
http://www.numaboa.com.br/criptografia/124-substituicao-simples/168-atbash
http://en.wikipedia.org/wiki/Atbash
http://mysteriouswritings.com/the-atbash-cipher-and-jeremiah-511/

Publicado em Criptografia | Marcado com , , , , | 1 Comentário

Desbloqueando arquivos PDF

Recentemente precisei unir alguns arquivos PDF em um só. Mas, ao tentar uni-los, descobri que todos os PDF possuíam proteção e não me permitiam fazer a união.

Busquei uma solução livre e acabei encontrando um comando utilizando o Ghostscript:

gswin32 -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite
-sOutputFile=pdf_desbloqueado.pdf -c .setpdfwrite
-f pdf_bloqueado.pdf

onde, pdf_bloqueado.pdf é o nome do arquivo PDF bloqueado e pdf_desbloqueado.pdf é o nome que será dado ao PDF depois de desbloqueado, e o comando deve ser digitado em uma linha só. Caso você utilize alguma versão do Linux troque gswin32 por gs.

Publicado em Soluções | Marcado com , , , | 2 Comentários