用python编写验证码

作为一个用python的生信工程师,平时工作中除了用python来处理些文本文件和搭建流程,没事也想探索些其他有趣的功能。这几天就在网上学习了下如何用python编写验证码,感兴趣的同学也一起来学习下吧!

01

验证码的作用及干扰机制

在编写验证码之前,我们首先来了解下验证码是用来干嘛的吧:

验证码主要是为了防止暴力破解,爬虫模拟登陆以及各种键盘钩子进行登陆;验证码能起到干扰作用的机制主要是靠背景点或线条进行干扰,以及对文字进行扭曲。

02

Python编写验证码实战

我们先来看下采用python编写验证码的一个基本思路:

1.定义一张图片

2.创建画笔

3.绘制线条和点

4.绘制文字

5.定义扭曲的参数

6.使用滤镜

下面我们分步来看一下每一步的代码实现是怎样的吧(注:这里采用的是python2进行编写):

01

导入模块

import randomfrom PIL import Image,ImageDraw,ImageFont,ImageFilter

这里我们需要用到两个模块,random模块和PTL模块。random模块用来生成随机数,PIL是一个用来处理图片文件的python第三方模块。PIL没有安装的小伙伴可以采用pip install PIL进行安装。PIL中的Image类负责处理图片,ImageDraw负责处理画笔, ImageFont负责处理字体,ImageFilter负责处理滤镜。

02

定义一张图片

img = Image.new("RGB",(150,50),(255,255,255))

这里需要用到三个参数,分别代表我们采用RGB颜色模式,图片的大小,具体的图片颜色。

03

创建画笔

draw = ImageDraw.Draw(img)

04

绘制线条和点

绘制线条

for i in range(random.randint(1,10)):
    draw.line(    
#在绘制线条时:每条线有两个点,每个点靠x,y两个值来确定位置       [
            ( random.randint(1,150),random.randint(1,150)),( 
random.randint(1,150),random.randint(1,150))
        ],
 fill = (0,0,0)  )

这里random.randint(1,10)函数用来生成1-10之间的随机数,draw.line是用来绘制线条的函数,由于一条线是由两个点组成,所以这里我们采用列表来储存线条的起止坐标。由于验证码中线条的作用就是起干扰作用,所以我们需要绘制出来的线条是没有规律的。这里循环用以生成线条的条数以及线条的起止坐标都采用random函数来随机生成。fill用来给出线条的RGB颜色。

绘制点

for i in range(2000):
draw.point(
        (random.randint(1,150),random.randint(1,150)),
                fill =(0,0,0)
            )

同理,我们可以绘制随机坐标的点,这里可以用循环控制绘制点的数量。

05

绘制文字

fontList = list("abdfkjfalemvcjierASDFGHJKLQW123456789")
c_chars = " ".join(random.sample(fontList,5)
#random.sample是在指定的列表当中随机取出指定个元素
font = ImageFont.truetype("simsun.ttc",26)
draw.text((5,5),c_chars,font=font,fill="green")

接下来我们就要绘制显示在验证码上的文字啦,在绘制文字的时候我们要考虑两点,首先我们生成的文字是要随机产生的,另外文字的个数需要是固定的。

这里我们首先利用fontList变量来定义要生成的随机数的字母和数字,接着我们要从定义的随机数列表当中取出指定个数的随机数。这里就要用到random.sample这个函数啦,函数后面接的参数就是取出的随机数的个数,其后我们用join函数将取出的随机数列表连接成字符串。随后用ImageFont.truetype定义字体,函数的第一个参数代表字体类别,第二个参数代表字体大小。最后采用draw.text进行文字的最终绘制,这里第一个参数代表文字的位置,距离上和左方的距离,第二个参数代表文字的内容,第三个参数代表字体,第四个参数定义字体的颜色。

06

定义扭曲参数

params = [1 - float(random.randint(1,2))/100,
          0,
          0,
          0,
          1 - float(random.randint(1,2))/100,
          float(random.randint(1,2))/500,
          0.001,
          float(random.randint(1,1))/500,
          ]

这里的参数有点多,这里就不详细介绍每个数值的含义啦,感兴趣的小伙伴可以自行百度搜索一下。

07

使用滤镜

img = img.transform((150,50),Image.PERSPECTIVE,params)  # 创建扭曲
"""
第一个参数:扭曲的范围,
第二个参数:扭曲的样式,
第三个参数:扭曲的参数
"""
img = img.filter(ImageFilter.EDGE_ENHANCE_MORE) #滤镜,边界加强(阈值更大)
img.show()

接下来我们就要使用滤镜来对文字进行扭曲,首先使用img.transform这个函数来创建扭曲,其中的三个参数,分别代表扭曲的范围、扭曲的样式、扭曲的参数,接着使用img.filter来进行扭曲。

最后我们来看下生成的效果吧:

是不是很简单呢,上述代码我们也可以封装成函数进行编写,感兴趣的小伙伴们可以自己动手试下哦。

我们在学习python的过程中可以多找一些自己感兴趣的项目来练习提高自己的编程能力,比如多练习下生信技能树中的生信编程题,也可以找一些自己感兴趣的应用来学习,比如试着用爬虫爬取自己感兴趣的内容,也可以试着用python写一些小游戏玩玩,人生苦短,我用python,让我们一起在学习练习中进步吧!

原文发布于微信公众号 - 生信技能树(biotrainee)

原文发表时间:2017-09-07

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏张善友的专栏

Miguel de Icaza 细说 Mix 07大会上的Silverlight和DLR

Mono之父Miguel de Icaza 详细报道微软Mix 07大会上的Silverlight和DLR ,上面还谈到了Mono and Silverligh...

2667
来自专栏芋道源码1024

熔断器 Hystrix 源码解析 —— 断路器 HystrixCircuitBreaker

本文主要基于 Hystrix 1.5.X 版本 1. 概述 2. HystrixCircuitBreaker 3. HystrixCircuitBreaker....

5277
来自专栏我和未来有约会

Kit 3D 更新

Kit3D is a 3D graphics engine written for Microsoft Silverlight. Kit3D was inita...

2506
来自专栏pangguoming

Spring Boot集成JasperReports生成PDF文档

由于工作需要,要实现后端根据模板动态填充数据生成PDF文档,通过技术选型,使用Ireport5.6来设计模板,结合JasperReports5.6工具库来调用渲...

1.2K7
来自专栏跟着阿笨一起玩NET

c#实现打印功能

2622
来自专栏落花落雨不落叶

canvas画简单电路图

59211
来自专栏张善友的专栏

LINQ via C# 系列文章

LINQ via C# Recently I am giving a series of talk on LINQ. the name “LINQ via C...

2625
来自专栏转载gongluck的CSDN博客

cocos2dx 打灰机

#include "GamePlane.h" #include "PlaneSprite.h" #include "BulletNode.h" #include...

5346
来自专栏码匠的流水账

聊聊NettyConnector的start及shutdown

reactor-netty-0.7.6.RELEASE-sources.jar!/reactor/ipc/netty/NettyConnector.java

841
来自专栏张善友的专栏

Mix 10 上的asp.net mvc 2的相关Session

Beyond File | New Company: From Cheesy Sample to Social Platform Scott Hansel...

2527

扫码关注云+社区