Experiência de OCR: Quebrando captcha com 26 linhas de código Python!

Durante este último mês, estive desenvolvendo uma solução GED utilizando a biblioteca de OCR Pytesser aliada à já conhecida e poderosa biblioteca de manipulação de imagens do Python, a PIL, que é utilizada em larga escala em soluções como Google Maps, Yahoo Maps e até mesmo no Youtube. Originalmente inspirado por um post[0] da Bonsai Security resolvi tentar a quebra de um captcha simples utilizando Pytesser e PIL.

CAPTCHA é um acrônimo da expressão “Completely Automated Public Turing test to tell Computers and Humans Apart” (teste de Turing público completamente automatizado para diferenciação entre computadores e humanos): um teste de desafio cognitivo, utilizado como ferramenta anti-spam, desenvolvido pioneiramente na universidade de Carnegie-Mellon. Como o teste é administrado por um computador, em contraste ao teste de Turing padrão que é administrado por um ser humano, este teste é na realidade corretamente descrito como um teste de Turing reverso.

O consenso geral é que isso seria fácil, mas o problema é conseguir uma solução de quebra de captcha que qualquer um possa fazer download e rodar em seu computador; Então o pessoal da Bonsai criou em alguns minutos um simples script Python que eu testei com vários exemplos de imagens e acabei utilizando o mesmo conceito para outras aplicações. A grande sacada está em utilizar httplib ou urllib para fazer a chamada aos arquivos de imagem. Antes de qualquer coisa tenha em mente: Isso é uma experiência didática. Geralmente não encontramos captchas fracos por ai e neste exemplo trabalharemos exclusivamente com este tipo de catpcha:

  • As letras não são rotacionadas
  • As letras possuem a mesma largura
  • As imagens são do mesmo tamanho
  • Não sofrem deformações
  • Plano de fundo é o mesmo para toda a imagem

Agora, vamos entender o código que quebra este captcha:

from PIL import Image
#Imagem a ser quebrada, neste ponto você poderia usar urlib, httplib ou curl para carregar esta imagem.
img = Image.open('input.gif')
#convertemos para o padrão RGB
img = img.convert("RGBA")
#damos bind da imagem para a variável pixdata
pixdata = img.load()

# Limpando a sujeira do background, se a cor for != black, então transformamos em branco.
for y in xrange(img.size[1]):
    for x in xrange(img.size[0]):
        if pixdata[x, y] != (0, 0, 0, 255):
            pixdata[x, y] = (255, 255, 255, 255)

#Salvamos a nova imagem com fundo branco
img.save("input-black.gif", "GIF")

#   Aumentamos as dimensões da imagem (requerido pelo OCR)
im_orig = Image.open('input-black.gif')
big = im_orig.resize((116, 56), Image.NEAREST)

#Salvamos a imagem com tamanho maior
ext = ".tif"
big.save("input-NEAREST" + ext)

#   Yeah! Fazemos OCR da imagem usando o Pytesser
from pytesser import *
image = Image.open('input-NEAREST.tif')
#simplesmente imprimimos a imagem em formato de string OCRizado
print image_to_string(image)

resultado:

python ocrcaptcha.py
>>> e4ya
>>> jxt9

Esta simples código, quebra 90% de qualquer captcha que utilize esta implementação. Aconselho fortemente aos programadores Pythonistas, para ficarem de olho no Pytesser, uma biblioteca excelente para OCR, com a qual tenho tido muito sucesso ultimamente! 🙂

[0] Bonsai

Aconselho a leitura deste post -> http://under-linux.org/blogs/magnun/brincando-com-python-e-pil-392/

Abraços

Bruno Rocha

Mais artigos deste autor »

Desenvolvedor e consultor web. Possui mais de 9 anos de experiência em desenvolvimento web e já trabalhou com as linguagens C, PHP, ASP, C#.

Atualmente, ministra treinamentos, palestras e desenvolve soluções com Python para web com os frameworks Pylons e web2py.

Um dos colaboradores do http://web2pybrasil.appspot.com e as vezes escreve também no blog http://rochacbruno.com.br

Além dos projetos com Python, atua como desenvolvedor e coordenador de projetos (ScrumMaster) na empresa GENTE - http://servicogente.com.br

Contato:
http://twitter.com/rochacbruno / rochacbruno[gmail.com]


9 Comentários

walter
3

ola bruno
gostaria de conversar com voce
sobre um trabalho deste nivel
como poderiamos fazer?
obrigado
aguardo

Michael
9

Boa Noite, estou necessitando quebrar um captcha simples utilizando c#.
Teria como me auxiliar?
Grato

Deixe seu comentário

Seu endereço de e-mail não será publicado. Campos com * são obrigatórios!