Python实现生成随机验证码附代码!

准备工作

好了,下面进入正题,我们来实现这个功能。首先这个是使用Python3进行开发的,我们需要用到一个PIL的库,这里安装库的pip3命令

为:pip3 install pillow。这里如果超时报错的话,我们可以使用cch。

然后我们创建一个captcha.py文件用来存放生成随机验证码的代码。这里面captcha的意思是“Completely Automated Public Turing test to tell Computers and Humans Apart”(全自动区分计算机和人类的图灵测试)的缩写,也就是我们俗称的验证码。

这里我们将随机生成验证码的这个功能写成一个类Captcha,然后我们通过这个类的方法来生成随机图片验证码。使用类进行封装的话,可以对类内的部分私有方法进行封装,提高安全性。下面我们就来一步一步的实现生成随机验证码的各个功能。

我们本功能将会使用到3个库,我们先进行导入。

我们从PIL中导入Image,ImageDraw,ImageFont:

import random
import string
from PIL import Image,ImageDraw,ImageFont
# 这里面Image是PIL中的画布,ImageDraw是画笔,ImageFont是画笔的字体

设置我们类的一些基础参数

我们这里将生成随机验证码写成了一个Captcha类,下面我们来设置一些他的基础参数,

我们一般需要设置的有图像验证码的宽、高,验证码位数、干扰线条数量、验证码大小、然后我们还需要构建一个验证码字符的源文件,这里各个部分在代码中进行了详细的注释,我们边看代码边看看注释!

import random
import string
from PIL import Image, ImageDraw, ImageFont
# 这里面Image是PIL中的画布,ImageDraw是画笔,ImageFont是画笔的字体
class Captcha(object):
    # 生成随机验证码的位数,可以根据需要进行修改
    number = 4
    # 干扰线条的条数
    line_number = 2
    # 生成验证码图片的宽和高,可以根据需要进行修改
    size = (100,40)
    # 验证码字的大小,可以根据需要进行修改
    fontsize = 24
    # 建立验证码源文本
    # list(string.ascii_letters) ASCII码中所有的字母
    SOURCE = list(string.ascii_letters)
    # 再加入'0'到'9'
    for index in range(10):
        SOURCE.append(str(index))

生成随机验证码文本

这里生成随机验证码的文本,我们只需要在SOURCE中随机的选取number个字符即可。

# 生成验证码文本
@classmethod
def __gene_random_captcha(cls,number):
    # number为验证码位数,返回字符串
    return ''.join(random.sample(cls.SOURCE,number))

生成随机字体

这里我们来实现生成随机字体的函数,因为同样的字,不同的字体,他的形状也是不一样的,所以这里我们的字体也是采用随机的。

那么要生成随机的字体,那么首先我们就要先要有字体的文件。

Windows下的字体文件路径为C/Windows/Fonts/,MacBook下的字体文件路径为/System/Library/Fonts/,如果找不到的话,可以看之前的一篇博文,内有详细的介绍:在Windows下和MacBook中如何查找本地的字体文件

在找到我们的字体文件之后,我们将它拖入到一个固定的文件夹,便于我们后面去获取这些字体文件。

这里由于我这边是在之前OnlineForumPlatform项目中做的,所以这里将它放在了/static/font/文件夹下。

下面我们来实现我们的随机生成字体的函数。首先我们写一个fonts列表,存放所有我们有的字体的文件名称,这里大家根据自己的字体文件而定。代码为:

# 生成随机字体
@classmethod
def __generate_random_font(cls):
    # 这里的fonts即是我们所有字体文件的名称,这里我是只复制过来了这么多,所以他的列表的这样,大家根据自己他字体文件来写这个fonts
    fonts = [
        'Palatino.ttc',
        'PingFang.ttc',
        'STHeiti Light.ttc',
        'STHeiti Medium.ttc',
        'Thonburi.ttc',
        'Times.ttc'
    ]
    font = random.choice(fonts)
    # 这里前面的字符为我们字符文件的文件夹位置
    return '/static/font/'+font

生成随机颜色

这里由于我们是使用RGBA来表示颜色,所以我们在各个颜色的值的范围为[0,255],我们这里可以设置默认的值为0和255,然后我们返回3种颜色的随机数值即可;

# 生成随机颜色
@classmethod
def __gene_random_color(cls,start=0,end=255):
    # start为最小值,end为最大值,这里因为是RGB格式的,我们每个颜色的值最小为0,最大为255,所以这里默认为0和255
    random.seed()
    # 返回3种颜色的值
    return (random.randint(start,end),random.randint(start,end),random.randint(start,end))

生成随机干扰线

绘制干扰线可以让我们的验证码不那么容易被软件轻松的破解,添加他的干扰项。

# 绘制干扰线
@classmethod
def __gene_line(cls,draw,width,height):
    # 干扰性的开始位置和结束位置
    begin = (random.randint(0,width),random.randint(0,height))
    end = (random.randint(0,width),random.randint(0,height))
    # 第一个参数为开始的位置和结束的位置,第二个参数的线的颜色,第三个参数为宽度
    draw.line([begin,end],fill = cls.__gene_random_color(0,255),width=2)

生成随机干扰点

绘制干扰点可以让我们的验证码不那么容易被软件轻松的破解,添加他的干扰项。

# 绘制干扰点

@classmethod
def __gene_points(cls,draw,ponit_chance,width,height):
    # chance为界限,如果当前随机数大于他,则绘制一个干扰电
    chance = min(100,max(0,int(ponit_chance)))
    # 遍历图
    for i in range(height):
        for j in range(width):
            temp = random.randint(0,100)
            if temp > chance:
                # 绘制干扰点,第一个参数为位置,第二个参数为颜色
                draw.point((j,i),fill = cls.__gene_random_color(0,255))

生成随机图片验证码

在完成各个功能函数之后,最后我们来实现我们生成随机图片验证码的函数。这里我们边看代码边解释各个的原理,在代码中进行了非常详细的一个注释说明。

# 生成图片验证码
@classmethod
def generate_graph_captcha(cls):
    # 验证码图片的宽和高,这里的size是我们上面进行设置的宽和高
    width,height = cls.size
    # 创建一个画布
    # 第一个参数为颜色的类型RGBA型,第二个参数为宽和高,第三个参数为颜色的值,这里调用__gene_random_color,这里我们参数颜色值可以自己进行修改
    image = Image.new('RGBA',(width,height),cls.__gene_random_color(0,100))
    # 设置验证码的字体
    # 第一个参数为字体的值,即我们使用什么字体,我们调用生成随机字体的函数。第二个参数为字体大小,在上面我们设置了默认值,可以进行修改
    font = ImageFont.truetype(cls.__generate_random_font(),cls.fontsize)
    # 创建画笔,并且绑定到上面创建的画布image上
    draw = ImageDraw.Draw(image)
    # 生成随机验证码文本,参数为验证码位数
    captcha_str = cls.__gene_random_captcha(cls.number)
    # 获取字体的尺寸
    font_width,font_height = font.getsize(captcha_str)
    # 设置我们绘制的位置,这里为了验证码尽量在中间,我们选择了中间点,大家可以根据需要进行修改
    position = ((width - font_width)/2, (height - font_height)/2)
    # 填充字符串
    # 第一个参数为绘制的位置,第二个参数为文本,这里使用生成的验证码文本,第三个参数为字体,第四个参数为文字的颜色
    draw.text(position, captcha_str,font = font,fill = cls.__gene_random_color(150,255))
    # 绘制干扰性
    for i in range(cls.line_number):
        cls.__gene_line(draw,width,height)
    # 绘制干扰点
    cls.__gene_points(draw,90,width,height)
    # open的第一个参数的文件名称,在这里也可以在前面加上文件夹的名,例如/static/captcha.png,第二个参数为打开方式
    with open('captcha.png','wb') as fp:
        image.save(fp)
    return (captcha_str,image)

调用方法,生成随机验证码

  到这里我们的功能已经完全的实现啦,然后我们只需要创建我们的对象,然后调用方法Captcha.generate_graph_captcha()即可在指定的位置生成我们的验证码图像。

97f1d4bf2b7c2a24b6dc0d8f986743a.png

更多Python知识,请关注云海天Python教程!!

来源:PY学习网:原文地址:https://www.py.cn/article.html

hmoban主题是根据ripro二开的主题,极致后台体验,无插件,集成会员系统
自学咖网 » Python实现生成随机验证码附代码!