python-生成验证码

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()

效果如下
在这里插入图片描述
输入正确的话关闭窗口,输入错误的话会更新图片。
就酱~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值