Created
April 17, 2015 19:23
-
-
Save pardo-bsso/a6ab7aa41bad3ca32e30 to your computer and use it in GitHub Desktop.
Captcha breaking code. See http://tangopardo.com.ar/2cf7/2015/04/17/breaking-a-simple-captcha-with-python-and-pillow
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
from PIL import Image | |
import sys, os | |
imgpatrones = [] | |
pixelpatrones = [] | |
for idx in range(10): | |
img = Image.open("patrones/%i.png" % idx).convert('RGB') | |
imgpatrones.append(img) | |
pixelpatrones.append( list(img.getdata()) ) | |
def compara(region, patron): | |
pixels = list(region.getdata()) | |
size = min(len(pixels), len(patron)) | |
res = 0.0 | |
for idx in range(size): | |
if pixels[idx] == patron[idx]: | |
res = res + 1 | |
return res / size | |
def elimina_lineas(src): | |
cropeada = src.crop( (4, 1, 49, 19) ) | |
w,h = cropeada.size | |
stripes = [] | |
for x in range(w): | |
count = 0 | |
for y in range(h): | |
if cropeada.getpixel( (x,y) ) != (248, 255, 255): | |
count += 1 | |
if count == h: | |
stripes.append(x) | |
for x in stripes: | |
for y in range(h): | |
cropeada.putpixel( (x,y), (248, 255, 255) ) | |
cropeada.putpixel( (x,y), (255, 0, 0) ) | |
return cropeada | |
def crear_crops(src, celda): | |
limites = range(38) | |
xceldas = [0, 8, 16, 24, 32, 40] | |
xoffsets = range(-3,4) | |
yceldas = range(6) | |
boxes = [] | |
crops = [] | |
x = xceldas[celda] | |
x = [ (x+off) for off in xoffsets if (x+off) in limites ] | |
for left in x: | |
for top in yceldas: | |
boxes.append( (left, top, left+8, top+13) ) | |
for box in boxes: | |
crops.append( src.crop(box) ) | |
return crops | |
def compara_crops_con_patron(crops, patron): | |
scores = [] | |
for crop in crops: | |
scores.append( compara(crop, pixelpatrones[patron] )) | |
return max(scores) | |
def decodifica_celda(src, celda): | |
pesos = [] | |
crops = crear_crops(src, celda) | |
for patron in range(10): | |
pesos.append( compara_crops_con_patron(crops, patron) ) | |
return pesos.index( max(pesos) ) | |
def decodifica(filename): | |
original = Image.open(filename) | |
src = elimina_lineas(original) | |
res = [] | |
for celda in range(6): | |
res.append( decodifica_celda(src, celda) ) | |
return ''.join( str(x) for x in res ) | |
if __name__ == '__main__': | |
print decodifica(sys.argv[1]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment