Quebrando CAPTCHAs - Parte II: O pacote decryptr

Por Julio 10/07/2017

No meu último post anunciei que começaríamos uma série sobre CAPTCHAs. Uma da nossas iniciativas principais nesse tema é a criação do pacote decryptr. Hoje veremos como usar algumas das funções principais desse pacote.

Suposições do decryptr

Ao criar o decryptr reduzimos um pouco o escopo de CAPTCHAs que gostaríamos de incluir. Fizemos isso para não ficarmos malucos, pois existem diversos tipos de testes disponíveis na web!

As suposições são:

  1. Apenas imagens jpg ou png.
  2. Uma imagem possui apenas números e letras.
  3. A quantidade de caracteres de um CAPTCHA é fixa.
  4. Dois CAPTCHAs de mesma origem têm sempre as mesmas dimensões.
  5. Não conseguimos nem queremos quebrar o reCAPTCHA.

Instalação

O decryptr ainda não está no CRAN. Isso significa que para instalá-lo você precisará do devtools:

if (!require(devtools)) install.packages('devtools')
devtools::install_github('decryptr/decryptr')

As funções principais do decryptr são

  • download(): baixar imagens da web.
  • read_captcha(): adiciona metadados úteis a uma string com o caminho do CAPTCHA.
  • load_captcha(): carrega a imagem na memória.
  • plot.captcha(): método S3 para desenhar o CAPTCHA na tela.
  • classify.captcha(): método S3 para classificar CAPTCHAs manualmente.
  • prepare.captcha(): método S3 para carregar CAPTCHAs em um formato adequado para modelagem usando o Keras.
  • model.captcha(): método S3 para modelar os CAPTCHAs.
  • predict.captcha(): método S3 para classificar um CAPTCHA a partir de um modelo ajustado e um caminho de imagem.

Fluxo de utilização

O modo de uso planejado do decryptr está descrito na Figura 1.

Figure 1: Fluxo de utilização do pacote decryptr.

Como ainda não temos a teoria completa para ajuste de modelos, nesse post vamos ficar com a utilização das funções de download, visualização e classificação.

Download

A função download() tem cinco parâmetros:

  • url= o link do CAPTCHA que queremos baixar.
  • dest= a pasta que queremos salvar a imagem.
  • n= a quantidade de CAPTCHAs a serem baixados.
  • secure= se TRUE, fará o download com a opção ssl_verifypeer = FALSE (veja esse post)
  • type= extensão do arquivo (jpg/jpeg ou png).

Essa não é uma das funções mais seguras do mundo, já que dependemos de uma boa conexão com o servidor de onde os CAPTCHAs serão baixados. A função também não trata de problemas com bloqueio de IP.

Para facilitar a utilização do decryptr, adicionamos algumas funções do tipo download_*(), que já contêm os padrões para download de alguns sites específicos:

Nesses casos, os únicos parâmetros são dest= e n=. Exemplo:

library(decryptr)
download_tjmg('img/tjmg', n = 5) # salva arquivo em ./img/tjmg/captcha<id>.jpeg

Visualização

Para plotar um CAPTCHA basta ler o arquivo com read_captcha() e depois usar a função plot(). Exemplo:

library(decryptr)
'img/tjmg/captcha4d2f795d4e4_92522.jpeg' %>% 
  read_captcha() %>% 
  plot()
CAPTCHA do TJMG.

Figure 2: CAPTCHA do TJMG.

Vale mencionar que esse não é um ggplot() então nem tente somar layers nesse gráfico 😄.

Classificação

A classificação manual de CAPTCHAs é importante para possibilitar o treino de modelos preditivos. Para classificar um CAPTCHA você pode utilizar a função classify(), assim:

'img/tjmg/captcha4d2f795d4e4_92522.jpeg' %>% 
  read_captcha() %>% 
  classify()

Essa função fará duas coisas:

  • Plota o CAPTCHA na tela.
  • Abre um console para o usuário digitar o valor do CAPTCHA manualmente.

Ao escrever o valor o CAPTCHA, pressione <enter>. Após isso, a função classify() irá adicionar sua classificação após o nome da imagem, como no exemplo acima: _92522. A função classify() gera uma cópia para que seja impossível de perder a imagem original.

Algumas opções do classify():

  • dest= colocar uma pasta para classificar os CAPTCHAs. Por padrão é a pasta onde os originais estão.
  • answer= adicionar uma resposta ao invés de esperar abrir o console. Essa opção é útil quando as classficações são feitas automaticamente (e.g., por um quebrador de CAPTCHAs que usa o áudio no lugar da imagem.)

Wrap-up

  • Baixar com download() ou download_*().
  • Visualizar com read_captcha() pipe plot().
  • Classificar com read_captcha() pipe classify().

Caso encontre problemas, adicione issues no repositório do pacote.

É isso. Happy coding ;)

comments powered by Disqus