Maison >développement back-end >Tutoriel Python >Explication détaillée de l'utilisation de Python pour déchiffrer le code d'exemple de code de vérification

Explication détaillée de l'utilisation de Python pour déchiffrer le code d'exemple de code de vérification

高洛峰
高洛峰original
2017-03-23 16:45:491657parcourir

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
Explication détaillée de lutilisation de Python pour déchiffrer le code dexemple de code de vérification
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. : Explication détaillée de lutilisation de Python pour déchiffrer le code dexemple de code de vérification
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)]
Reconnaissance d'images par l'IA et l'espace vectoriel


Ici, nous utilisons le moteur de recherche spatiale pour la reconnaissance des caractères. présente de nombreux avantages :

Il ne nécessite pas un grand nombre d'itérations d'entraînement
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
Il ne sera pas surentraîné

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.

Dernier contenu ajouté :
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 l'intégralité du contenu de cet article. J'espère que le contenu de cet article pourra être utile aux études ou au travail de chacun. Si vous avez des questions, vous pouvez partir. un message à communiquer.


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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn