Criptografia com Python (02)
Vamos começar! Vamos fazer mais e falar menos.
Neste capítulo, construiremos um algoritmo de maneira simples (tosca) para criptografar uma mensagem e conheceremos outros padrões.
Abra seu editor ou IDE favorito e crie um arquivo chamado mensagem_screta.py e escreva os códigos no passo a passo para aprender.
Vamos criptografar!
Considere que temos uma mensagem que preicisará ser salva em uma variável de texto (mensagem_secreta) e inverter a ordem de escrita.
Então, se temos a mensagem “ABC” precisaremos inverter e criptografar esta mensagem para que, quem for receber, tenha apenas “CBA”.
Vamos ao método mais tosco de todos. Primero, vamos inverter uma lista (lembre-se que apenas LISTA ou ARRAY possui a função de inversão que não se aplica para TUPLES ou OBJETOS. Listas ou Arrais são inicializadas com colchetes e Tuples ou Objetos são imutáveis e inicializados com parênteses):
lista = ["a", "b", "c", "d", "e", "f", "g", "h"]
lista.reverse()
print(lista)
A função reverse() inverte a ordem de uma lista. Simples!
O resultado será:
[‘h’, ‘g’, ‘f’, ‘e’, ‘d’, ‘c’, ‘b’, ‘a’]
Agora, vamos adicionar a função e a sintaxe do slice() na lista quando formos executar a saída de dados pela função print() com resultado (já invertido) de:
print(lista)
Para:
print(lista[::])
O resultado ainda será o mesmo do anterior com a função reverse(), mas, a sintaxe da função não foi declarada. Precisamos entender a função slice() que é possível ser feita de duas maneiras. Vou mostrar apenas uma, a mais prática.
A função Slice(start, end, step)
A função slice() possui a seguinte sintaxe:
slice(start, end, step)
START (Opcional) é o início do fatiamento. Aqui você pode especificar um número inteiro para dizer em qual posição deja iniciar o fatiamento.
O padrão da função, caso não informe um valor será de 0 (zero).
END (Opcional) é o fim do fatiamento. Aqui você pode especificar um número inteiro para dizer em qual posição deja finalizar o fatiamento.
O padrão da função, caso não informe um valor será de 1 (um).
STEP indica a ordem ou passo do fatiamento. Por padrão, caso não seja declarado, o valor padrão será 1 (um) em ordem crescente. Logo, se declarar o valor 1, ele vai correr a lista em ordem crescente de 1 em 1. Se quiser contar cada elemento de 2 em 2 (pulando um elemento), basta declarar 2.
Ou seja, se declarar o STEP como 1 terá:
[“1”, “2”, “3”, “4”, “5”, “6”, “7”, “8”]
Caso declare o STEP como 2, terá:
[“1”, “3”, “5”, “7”]
Caso declare o STEP como 3, terá:
[“1”, “4”, “7”]
E caso declare o STEP como 4, terá:
[“1”, “5”]
Então, quando usarmos a função slice() vamos usar a ordem inversa, ou seja, um número negativo no STEP da função slice() quando “printar” a lista.
Voltando para nossa lista de letras:
print(lista[::])
Nossa lista recebeu agora a função slice representada pelo colchete [] quando for ser impressa. Ainda não declaramos o STEP da função.
print(lista[::-1])
Agora, declaramos uma ordem do STEP com um número inteiro negativo. Ou seja, agora, esta função vai exibir a lista contando do último elemento até o primeiro.
lista = ["a", "b", "c", "d", "e", "f", "g", "h"]
print(lista[::-1])
O resultado vai ser o mesmo da reverse() usada anteriormente. Porém, agora temos como parametrizar a divisão do STEP ao inverte-lo de forma negativa.
print(lista[::-2])
Se aumentarmos o passo (de 1 para 2) e mante-lo invertido (negativo) vamos ter um resultado da leitura da lista invertida e “pulando” de 2 em 2:
[‘h’, ‘f’, ‘d’, ‘b’]
Isso ainda não é o melhor padrão de criptografia, mas, se considerar que sua mensagem secreta pode ser invertida ou embaralhada, já é interessante.
Vamos trocar a lista, por uma string, uma palavra comum: “PYTHON”.
E antes de fazer esta operação, precisa entender que um bom padrão de criptografia precisa de um bom padrão que contenha os 4 elementos já citados anteriormente, logo, precisa ser descriptografado corretamente.
Então, imagine a seguinte situação: um dia, você recebe uma carta e nela está escrito apenas a mensagem “NOHTYP” em seu conteúdo.
Alguns padrões são lógicos, mas, neste caso, uma palavra em outro idioma que não seja seu idioma nativo pode causar incompreensão, mas, se no lugar de “NOHTYP” houvesse uma palavra comum em nosso idioma nativo, por exemplo, se na carta houvesse a mensagem “LISARB”, seria óbio para você?
A mensagem é “BRASIL” — considernado que você perceberia que isso é um enigma ou saberia que era uma mensagem cifrada — não seria tão difícil de descriptografá-la com um pouco de observação e lógica.
Então, se você conhece o padrão, seus parâmetros (inversão de caracteres de 1 a 1), logo, não precisa nem de um software. Bastaria inverter cada letra para conseguir a mensagem. Simples, mas, você acabou de desenvolver um padrão.
Agota vamos para a construção do “criptografador” desta mensagem, já que você já descobriu (descriptografou) a mensagem NOHTYP, precisa entender como o algoritmo foi constrúido para pensar lá na frente em como criar o que inverte, ou, descriptografa a mensagem.
Para inverter uma string em Python, já sabe que pode usar o slice() e declarar o parâmetro step como um número inteiro negativo para isso. Então:
É RIDICULAMENTE MUITO SIMPLES!
O resultado impresso será NOHTYP.
Agora que você conhece a função, este padrão de criptografia vai começar a parecer bem fraco (e ele é). Então, vamos usar a função slice() usando o START e END além do STEP.
Então, se o STEP “separa e conta” cada letra ou elemento, a mensgaem secreta que usamos “PYTHON” tem a seguinte característica em contagem:
Se declarar o START como 1, ele vai iniciar a contagem após o número 1. É um conceito diferente de enumeração de listas ou arrays. Aqui, não temos o elemento zero (0) como primeiro item ou elemento da array.
Lembrando a sintaxe de slice():
slice[START:END:STEP]
Então, se não temos zero e ao declarar o STEP a função conta após o número declarado, se no START e END eu declarar 1 até 5 e um step de 1 em 1, temos:
print(mensagem_secreta[1:5:1])
Temos:
O resultado será então:
YTHO
Acabamos de criar um padrão. Ou seja, toda palavra tem sua primeira e sua última palavra subtraída. Mas, o padrão ainda continua fraco. O problema aqui não é criptografar. Este processo só faz sentido se puder ter um padrão para descriptografar uma mensagem, Como está, pode haver falhas de interpretação. Não é de verdade um sistema de criptografia.
Então, vamos considerar o seguinte:
- A mensagem precisa ser criptograda em um padrão.
- O mesmo padrão precisa oferecer a possibilidade de que alguém possa ter esta mensagem descriptografada usando o mesmo padrão.
Temos algumas opções para “incrementar” nosso algoritmo. Podemos inserir um contador de letras da string e incluir números entre as letras, substituirmos espaços por símbolos, letras ou números, enfim, há opções.
Pode incrementar seu algoritmo com:
print(len(mensagem_secreta))
Pode ainda parecer um pouco complexo, mas, se você chegou até aqui, entendeu que não é simples criar um padrão de criptografia.
É sim, complexo, precisa de regras e de lógica.
Poderia explicar, por exemplo, como funciona a lógica de outros padrões, mas, o Python já possui estas funções. Não precisa me odiar, mas, já existe fórmulas prontas para poder criptografar dados. Expliquei tudo isso até aqui para que possa entender de padrões, pois, mais a frente, ficaria complexo falar deste assunto. Confie em mim, isso aqui vai te ajudar muito!