SMO算法实在太难了,不想看了,做一个这个玩玩试试,随机生成验证码,用户输入并判读,成功就关闭,错误就换一张重新输入。
下一次就尝试利用算法识别验证码~
# -*- coding:utf-8 -*-
# version:python3.7.3
# author:hty
# date:2020.5.27
import pygame, sys, random
from pygame.locals import *
from PIL import Image, ImageDraw, ImageFont
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
FONT = "C:\Windows\Fonts\Arial.TTF"
allnum = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
# 从一个博主那里复制过来的,https://blog.csdn.net/qq_39687901/article/details/83620968,稍微做了一点修改,感谢博主
class TextBox:
def __init__(self, w, h, x, y, font=None):
"""
:param w:文本框宽度
:param h:文本框高度
:param x:文本框坐标
:param y:文本框坐标
:param font:文本框中使用的字体
:param callback:在文本框按下回车键之后的回调函数
"""
self.width = w
self.height = h
self.x = x
self.y = y
self.text = "" # 文本框内容
# 创建
self.__surface = pygame.Surface((w, h))
# 如果font为None,那么效果可能不太好,建议传入font,更好调节
if font is None:
self.font = pygame.font.Font(None, 30) # 使用pygame自带字体
else:
self.font = font
def draw(self, dest_surf):
text_surf = self.font.render(self.text, True, (255, 255, 255))
dest_surf.blit(self.__surface, (self.x, self.y))
dest_surf.blit(text_surf, (self.x, self.y + (self.height - text_surf.get_height())),
(0, 0, self.width, self.height))
def key_down(self, event):
unicode = event.unicode
key = event.key
# print(key)
# 切换中英文
if key == K_LSHIFT:
return
# 退位键
if key == 8:
self.text = self.text[:-1]
return
# 切换大小写键
if key == 301:
return
# 回车键
if key == 13:
self.text = self.text.lower()
# print(self.text)
# print(target)
if self.text == target.lower():
print('验证码输入正确')
return True
else:
print('验证码输入错误')
return False
if unicode != "":
char = unicode
else:
for i in range(10):
if key == 256+i:
char = str(i)
break
else:
char = chr(key)
self.text += char
# 创建框
def create_window():
global DISPLAY
pygame.init()
# 界面大小
DISPLAY = pygame.display.set_mode([200, 150])
# 标题
pygame.display.set_caption('hty的生成验证码')
# 把code照片贴上去
image = pygame.image.load('code.jpg')
DISPLAY.blit(image, (0, 2))
# please enter 文字
font = pygame.font.SysFont(FONT, 30)
surface = font.render('Please enter', False, (255, 200, 10))
# 那个白框
pygame.draw.rect(DISPLAY, [255, 255, 255], [25, 100, 150, 50], 1)
DISPLAY.blit(surface, (40, 80))
# 创建了1000个随机验证码
def createnumber():
fr = open('number.txt', 'w')
code_list = []
for i in range(1000):
num_1 = random.choice(allnum)
num_2 = random.choice(allnum)
num_3 = random.choice(allnum)
num_4 = random.choice(allnum)
code = num_1 + num_2 + num_3 + num_4
code_list.append(code)
for i in range(1000):
fr.write(code_list[i])
fr.write('\n')
fr.close()
# 从1000个当中随便选一个
def random_coice():
fr = open('number.txt', 'r')
random_num = random.randint(0, 1000)
line = fr.readlines()
return line[random_num]
fr.close()
# 将选出的验证码弄出图片的形式
def draw():
# 要拿去判断是否输入正确,把它弄成全局变量
global target
target = random_coice()[0:4]
# print(target)
myfont = ImageFont.truetype("C:\Windows\Fonts\Arial.TTF", 36)
length = 200
width = 60
# 创建验证码的图像
image = Image.new('RGB', (length, width), WHITE)
for i in range(4):
# 对每一个字所在的区域也创建图像
locals()['sum'+str(i)] = Image.new('RGB', (60, 60), WHITE)
# 往上面写字
draw = ImageDraw.Draw(locals()['sum'+str(i)])
txt = draw.text((random.randint(15, 20), random.randint(0, 20)), target[i], font=myfont, fill=RED)
# 做成旋转效果
locals()['sum'+str(i)] = locals()['sum' + str(i)].rotate(random.randint(-45, 45))
# 将这些图像再沾到开始创建的那个图像上去
image.paste(locals()['sum'+str(i)], (-10+50*i, 0))
# 旋转后,图像大小不变,造成四角有黑边,这个是再把黑边去掉,去掉之后发现带有一点红色边框的感觉,无心插柳柳成荫
for x in range(length):
for y in range(width):
dot = (x, y)
# print(dot)
color_d = image.getpixel(dot)
if color_d == (0, 0, 0):
color_d = (255, 255, 255)
image.putpixel(dot, color_d)
if color_d == RED:
color_d = (0, 0, 0)
image.putpixel(dot, color_d)
# 增加一些散点
for i in range(2000):
dot = (random.randint(0, 199), random.randint(0, 59))
# print(dot)
image.putpixel(dot, (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)))
# 保存在本地
image.save('code.jpg', 'jpeg')
# 主函数
def main_function():
# 先得到图像
draw()
# 创建窗口
create_window()
# pygame上文本框
text_box = TextBox(100, 20, 70, 120)
# 经典pygame.event.get()
while True:
pygame.display.flip()
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.KEYDOWN:
# 得到判断结果
result = text_box.key_down(event)
# 如果正确,关闭
if result == True:
pygame.quit()
sys.exit()
# 如果错误,更新新的验证码
if result == False:
main_function()
text_box.draw(DISPLAY)
main_function()
效果如下
输入正确的话关闭窗口,输入错误的话会更新图片。
就酱~