Python生成验证码

在开发中许多地方要用到验证码,验证码的一般限制用户进行表单提交的时候进行爆破,这篇文章记录Python如何生成验证码。

验证码的生成主要注意到这几点

  • 验证码的宽高
  • 验证码字体
  • 验证码内容
  • 干扰线
  • 噪点

满足这几点就可以生成一张验证码,下面代码是我之前学习Flask,copy别人的代码,之前都在用这串代码实现验证码功能,这里记录下,方便以后copy。

1
# -*- coding: UTF-8 -*-
2
import random
3
import string
4
# Image:一个画布
5
# ImageDraw:一个画笔
6
# ImageFont:画笔的字体
7
from PIL import Image, ImageDraw, ImageFont, ImageFilter
8
9
10
# pip install pillow
11
12
# Captcha验证码
13
14
class Captcha(object):
15
    # 生成几位数的验证码
16
    number = 4
17
    # 验证码图片的宽度和高度
18
    size = (100, 30)
19
    # 验证码字体大小
20
    fontsize = 25
21
    # 加入干扰线的条数
22
    line_number = 2
23
24
    # 构建一个验证码源文本
25
    SOURCE = list()
26
    for index in range(0, 10):
27
        SOURCE.append(str(index))
28
29
    # 用来绘制干扰线
30
    @classmethod
31
    def __gene_line(cls, draw, width, height):
32
        begin = (random.randint(0, width), random.randint(0, height))
33
        end = (random.randint(0, width), random.randint(0, height))
34
        draw.line([begin, end], fill=cls.__gene_random_color(), width=2)
35
36
    # 用来绘制干扰点
37
    @classmethod
38
    def __gene_points(cls, draw, point_chance, width, height):
39
        chance = min(100, max(0, int(point_chance)))  # 大小限制在[0, 100]
40
        for w in range(width):
41
            for h in range(height):
42
                tmp = random.randint(0, 100)
43
                if tmp > 100 - chance:
44
                    draw.point((w, h), fill=cls.__gene_random_color())
45
46
    # 生成随机的颜色
47
    @classmethod
48
    def __gene_random_color(cls, start=0, end=255):
49
        random.seed()
50
        return (random.randint(start, end), random.randint(start, end), random.randint(start, end))
51
52
    # 随机选择一个字体
53
    @classmethod
54
    def __gene_random_font(cls):
55
        fonts = [
56
            'verdana.ttf'
57
        ]
58
        font = random.choice(fonts)
59
        return 'utils/captcha/' + font
60
61
    # 用来随机生成一个字符串(包括英文和数字)
62
    @classmethod
63
    def gene_text(cls, number):
64
        # number是生成验证码的位数
65
        return ''.join(random.sample(cls.SOURCE, number))
66
67
    # 生成验证码
68
    @classmethod
69
    def gene_graph_captcha(cls):
70
        # 验证码图片的宽和高
71
        width, height = cls.size
72
        # 创建图片
73
        # R:Red(红色)0-255
74
        # G:G(绿色)0-255
75
        # B:B(蓝色)0-255
76
        # A:Alpha(透明度)
77
        image = Image.new('RGBA', (width, height), cls.__gene_random_color(0, 100))
78
        # 验证码的字体
79
        font = ImageFont.truetype(cls.__gene_random_font(), cls.fontsize)
80
        # 创建画笔
81
        draw = ImageDraw.Draw(image)
82
        # 生成字符串
83
        text = cls.gene_text(cls.number)
84
        # 获取字体的尺寸
85
        font_width, font_height = font.getsize(text)
86
        # 填充字符串
87
        draw.text(((width - font_width) / 2, (height - font_height) / 2), text, font=font,
88
                  fill=cls.__gene_random_color(150, 255))
89
        # 绘制干扰线
90
        for x in range(0, cls.line_number):
91
            cls.__gene_line(draw, width, height)
92
        # 绘制噪点
93
        cls.__gene_points(draw, 10, width, height)
94
        # image.filter(ImageFilter.EDGE_ENHANCE_MORE)
95
        return (text, image)