Implementando a Cifra de César em Ruby

A Cifra de César é a mais simples e conhecida técnica de encriptação. Ela também é conhecida por cifra de troca, código de César, troca de César, ROT N (ROT13 é a mais famosa delas, trocando as letras em treze rotações).

Este algoritmo é extremamente simples, pois somente funciona para letras entre A e Z, ignorando todos os caracteres especiais como pontos, espaços em branco e letras como Ç or Á.


Começando nossa implementação, vamos precisar criar uma classe responsável por saber o que queremos encriptar e quantas trocas vamos fazer.

Feito isso, precisamos trocar os caracteres pelo correspondente depois de N rotações, então vamos adicionar o método shift:

Neste ponto, nos deparamos com um pequeno problema. Se o valor de new_byte (o valor original em bytes somado com quantos bytes que desejamos trocar) for maior que Z ou z, é necessário voltar ao valor de A ou a novamente. Quando isso acontece, também é necessário subtrair um, pois temos que levar o valor do caractere inicial em consideração.

Neste código, initial_byte é referente ao valor de A ou a e limit_byte é o byte referente a Z ou z. Desta maneira, sempre vamos rotacionar entre as letras.

Vamos agora descobrir como é possível encontrar os bytes presentes em cada caractere de uma string. Olhando mais a fundo no Ruby, isto é facilmente feito pelo método bytes. Tendo conhecimento disto, temos o seguinte:

  • A é representado pelo byte 65.
  • Z é representado pelo byte 90.
  • a é representado pelo byte 97.
  • z é representado pelo byte 122.
=> [65, 90, 97, 122]

Então, o próximo passo é encontrar qual o valor que vamos usar para initial_byte e limit_byte ou se vamos ignorar este caractere. Para isso, vamos checar se os bytes dentro do texto fornecido estão dentro da variação de bytes para as letras que queremos, se não, vamos simplesmente retornar o valor do byte.

Em Ruby, a maneira mais fácil de converter estes bytes em uma string é chamando o método pack. Também é necessário fornecer ao método a opção c* como um parâmetro. Neste caso, c significa um valor inteiro positivo de 8-bit e * significa que todo o array deve ser convertido.

Com estes dois métodos somos capazes de encriptar uma mensagem utilizando a Cifra de César. Se quisermos decifrar uma mensagem, devemos trocar as letras na direção oposta, como código abaixo:

A ideia é a mesma do método shift, porém a troca é realizada na “outra” direção

Já o método decipher deve ser exatamente igual ao método cipher, portanto só é necessário duplicar o método cipher e trocar a assinatura do método para decipher.

Agora vamos finalmente testar o nosso código!

=> “Jul qvq gur puvpxra pebff gur ebnq?”

Também é possível decifrar uma mensagem:

=> “Why did the chicken cross the road?”

Uma coisa interessantíssima acontece quando nós utilizamos a quantidade de rotações igual a 13. Como temos 26 letras entre A e Z, não faz diferença nenhuma se chamamos o método cipher ou decipher, pois ele sempre vai retornar exatamente o mesmo resultado.

=> true

Para ter resultados diferentes, é necessário trocar a quantidade de rotações.


Infelizmente essa implementação tem um problema. Os caracteres em Ruby podem ser multi-bytes e originalmente não levei isto em consideração. Para que funcione ignorando os caracteres multi-bytes deve se implementar a solução utilizando divisão modular.

Este é minha primeira postagem sobre criptografia e minha ideia é implementar algumas das técnicas conhecidas e tentar explicar facilmente aqui. Se você tiver interesse em olhar o código completo, por favor acesse o repositório no Github.

Você também pode me encontrar no Twitter, Github, XING ou LinkedIn.