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()即可在指定的位置生成我们的验证码图像。
更多Python知识,请关注云海天Python教程!!
来源:PY学习网:原文地址:https://www.py.cn/article.html