1. Préface
Cette expérience expliquera le cracking à travers un exemple simpleLe principe du code de vérification, vous apprendrez et mettrez en pratique les points de connaissances suivants :
PythonConnaissances de base
Utilisation du module PIL
2. Explication détaillée d'exemples
Installer la bibliothèque Pillow (PIL) :
$ sudo apt-get update $ sudo apt-get install python-dev $ sudo apt-get install libtiff5-dev libjpeg8-dev zlib1g-dev \ libfreetype6-dev liblcms2-dev libwebp-dev tcl8.6-dev tk8.6-dev python-tk $ sudo pip install pillow
Télécharger les fichiers pour l'expérience :
$ wget http://labfile.oss.aliyuncs.com/courses/364/python_captcha.zip $ unzip python_captcha.zip $ cd python_captcha
Voici le code de vérification captcha.gif utilisé dans notre expérience
Extraire le texteImage
au travail Créez un nouveau fichier crack.py dans le répertoire et modifiez-le Sortie :
#-*- coding:utf8 -*- from PIL import Image im = Image.open("captcha.gif") #(将图片转换为8位像素模式) im = im.convert("P") #打印颜色直方图 print im.histogram()
Chaque bit de l'histogramme de couleur. pixels contenant la couleur correspondante dans l'image. Chaque pixel peut représenter 256 couleurs. Vous constaterez que le point blanc est le plus (la position du nombre blanc 255, qui est le dernier chiffre, comme vous pouvez le voir). sont 625 pixels blancs). Le pixel rouge est autour du numéro de série 200. Nous pouvons obtenir des couleurs utiles en triant
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0 , 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 1, 2, 0, 1, 0, 0, 1, 0, 2, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 3, 1, 3, 3, 0, 0, 0, 0, 0, 0, 1, 0, 3, 2, 132, 1, 1, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 15, 0 , 1, 0, 1, 0, 0, 8, 1, 0, 0, 0, 0, 1, 6, 0, 2, 0, 0, 0, 0, 18, 1, 1, 1, 1, 1, 2, 365, 115, 0, 1, 0, 0, 0, 135, 186, 0, 0, 1, 0, 0, 0, 116, 3, 0, 0, 0, 0, 0, 21, 1, 1, 0, 0, 0, 2, 10, 2, 0, 0, 0, 0, 2, 10, 0, 0, 0, 0, 1, 0, 625]
Sortie :
his = im.histogram() values = {} for i in range(256): values[i] = his[i] for j,k in sorted(values.items(),key=lambda x:x[1],reverse = True)[:10]: print j,k
Nous avons obtenu les 10 couleurs les plus présentes dans l'image, dont 220 et 227 sont le rouge et le gris dont nous avons besoin. Nous pouvons utiliser ces informations pour construire une image binaire en noir et blanc
255 625 212 365 220 186 219 135 169 132 227 116 213 115 234 21 205 18 184 15
Le résultat obtenu. :
#-*- coding:utf8 -*- from PIL import Image im = Image.open("captcha.gif") im = im.convert("P") im2 = Image.new("P",im.size,255) for x in range(im.size[1]): for y in range(im.size[0]): pix = im.getpixel((y,x)) if pix == 220 or pix == 227: # these are the numbers to get im2.putpixel((y,x),0) im2.show()
Extraire une image d'un seul personnage
Le prochain travail consiste à obtenir la collection de pixels d'un seul personnage. L'exemple étant relativement simple, nous allons effectuer un découpage vertical. :
Sortie :
inletter = False foundletter=False start = 0 end = 0 letters = [] for y in range(im2.size[0]): for x in range(im2.size[1]): pix = im2.getpixel((y,x)) if pix != 255: inletter = True if foundletter == False and inletter == True: foundletter = True start = y if foundletter == True and inletter == False: foundletter = False end = y letters.append((start,end)) inletter=False print letters
Obtenez les numéros de colonne de début et de fin de chaque caractère
(Suite du code ci-dessus)Coupez l'image pour obtenir la partie de l'image où se trouve chaque caractère.
[(6, 14), (15, 25), (27, 35), (37, 46), (48, 56), (57, 67)]
Ici, nous utilisons le moteur de recherche spatiale pour la reconnaissance des caractères. présente de nombreux avantages :
import hashlib import time count = 0 for letter in letters: m = hashlib.md5() im3 = im2.crop(( letter[0] , 0, letter[1],im2.size[1] )) m.update("%s%s"%(time.time(),count)) im3.save("./%s.gif"%(m.hexdigest())) count += 1
Vous pouvez ajouter/supprimer des données erronées à tout moment pour visualiser l'effet
C'est facile pour comprendre et écrit dans le code
Fournit des résultats hiérarchiques, vous pouvez afficher plusieurs correspondances les plus proches
Pour les choses non reconnues, ajoutez-les simplement au moteur de recherche et elles seront reconnues immédiatement Bien sûr, il a aussi des défauts, comme La vitesse de classification est beaucoup plus lente que celle des réseaux de neurones, et il ne peut pas trouver sa propre façon de résoudre les problèmes, etc. Le nom du moteur de recherche d'espace vectoriel semble très élevé, mais le principe est très simple :
Vous. Il y a 3 documents, comment calcule-t-on la similitude entre eux ? Plus deux documents utilisent de mots en commun, plus ils se ressemblent ! Mais que se passe-t-il s'il y a trop de mots ? C'est à nous de sélectionner quelques mots clés. Les mots sélectionnés sont aussi appelés caractéristiques. Chaque caractéristique est comme une dimension dans l'espace (x, y, z, etc.), et une. L'ensemble de fonctionnalités est un vecteur, nous pouvons obtenir un tel vecteur pour chaque document. Tant que nous calculons l'angle entre les vecteurs, nous pouvons obtenir la similitude des articles.
Utilisez la classe Python pour implémenter l'espace vectoriel :
Il comparera deux types de dictionnaire Python et affichera leur similarité (représentée par des nombres de 0 à 1)
Mettre le contenu précédent ensemble
Il y a aussi le travail d'extraction d'un grand nombre de codes de vérification pour extraire des images à un seul caractère en tant qu'ensemble de formation, mais tant que les étudiants auront lu attentivement ce qui précède, ils sauront certainement comment effectuer ces tâches. Il est omis ici. Vous pouvez directement utiliser l'ensemble de formation fourni pour effectuer les opérations suivantes.
Le répertoire Iconset contient notre ensemble de formation.
import math class VectorCompare: #计算矢量大小 def magnitude(self,concordance): total = 0 for word,count in concordance.iteritems(): total += count ** 2 return math.sqrt(total) #计算矢量之间的 cos 值 def relation(self,concordance1, concordance2): relevance = 0 topvalue = 0 for word, count in concordance1.iteritems(): if concordance2.has_key(word): topvalue += count * concordance2[word] return topvalue / (self.magnitude(concordance1) * self.magnitude(concordance2))
Obtenir le résultatTout est prêt, essayez d'exécuter notre code :
Sortie
#将图片转换为矢量 def buildvector(im): d1 = {} count = 0 for i in im.getdata(): d1[count] = i count += 1 return d1 v = VectorCompare() iconset = ['0','1','2','3','4','5','6','7','8','9','0','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'] #加载训练集 imageset = [] for letter in iconset: for img in os.listdir('./iconset/%s/'%(letter)): temp = [] if img != "Thumbs.db" and img != ".DS_Store": temp.append(buildvector(Image.open("./iconset/%s/%s"%(letter,img)))) imageset.append({letter:temp}) count = 0 #对验证码图片进行切割 for letter in letters: m = hashlib.md5() im3 = im2.crop(( letter[0] , 0, letter[1],im2.size[1] )) guess = [] #将切割得到的验证码小片段与每个训练片段进行比较 for image in imageset: for x,y in image.iteritems(): if len(y) != 0: guess.append( ( v.relation(y[0],buildvector(im3)),x) ) guess.sort(reverse=True) print "",guess[0] count += 1
C'est la bonne réponse, bravo.
Résumé
python crack.py
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!