Python编写生成验证码的脚本的教程


Posted in Python onMay 04, 2015

在web开发中经常用到验证码,为了防止机器人注册或者恶意登陆和查询等,作用不容小觑

但是验证码其实不是一个函数就能搞定的,它需要生成图片和水印,其实每种语言都有相关的函数生成图片和文字水印。包括我熟悉的php,呵呵,今天主要来分享如何用python生成验证码。

python生成验证码主要用到如下模块:Image, ImageDraw, ImageFont, ImageFilter和随机数生成模块Random。

代码如下:

#!/usr/bin/env python
#coding=utf-8
import random
import Image, ImageDraw, ImageFont, ImageFilter
 
_letter_cases = "abcdefghjkmnpqrstuvwxy" # 小写字母,去除可能干扰的i,l,o,z
_upper_cases = _letter_cases.upper() # 大写字母
_numbers = ''.join(map(str, range(3, 10))) # 数字
init_chars = ''.join((_letter_cases, _upper_cases, _numbers))
fontType="/usr/share/fonts/truetype/freefont/FreeSans.ttf"
 
def create_validate_code(size=(120, 30),
               chars=init_chars,
               img_type="GIF",
               mode="RGB",
               bg_color=(255, 255, 255),
               fg_color=(0, 0, 255),
               font_size=18,
               font_type=fontType,
               length=4,
               draw_lines=True,
               n_line=(1, 2),
               draw_points=True,
               point_chance = 2):
 '''
 @todo: 生成验证码图片
 @param size: 图片的大小,格式(宽,高),默认为(120, 30)
 @param chars: 允许的字符集合,格式字符串
 @param img_type: 图片保存的格式,默认为GIF,可选的为GIF,JPEG,TIFF,PNG
 @param mode: 图片模式,默认为RGB
 @param bg_color: 背景颜色,默认为白色
 @param fg_color: 前景色,验证码字符颜色,默认为蓝色#0000FF
 @param font_size: 验证码字体大小
 @param font_type: 验证码字体,默认为 ae_AlArabiya.ttf
 @param length: 验证码字符个数
 @param draw_lines: 是否划干扰线
 @param n_lines: 干扰线的条数范围,格式元组,默认为(1, 2),只有draw_lines为True时有效
 @param draw_points: 是否画干扰点
 @param point_chance: 干扰点出现的概率,大小范围[0, 100]
 @return: [0]: PIL Image实例
 @return: [1]: 验证码图片中的字符串
 '''
 
 width, height = size # 宽, 高
 img = Image.new(mode, size, bg_color) # 创建图形
 draw = ImageDraw.Draw(img) # 创建画笔
 if draw_lines:
  create_lines(draw,n_line,width,height)
 if draw_points:
  create_points(draw,point_chance,width,height)
 strs = create_strs(draw,chars,length,font_type, font_size,width,height,fg_color)
 
 # 图形扭曲参数
 params = [1 - float(random.randint(1, 2)) / 100,
      0,
      0,
      0,
      1 - float(random.randint(1, 10)) / 100,
      float(random.randint(1, 2)) / 500,
      0.001,
      float(random.randint(1, 2)) / 500
      ]
 img = img.transform(size, Image.PERSPECTIVE, params) # 创建扭曲
 
 img = img.filter(ImageFilter.EDGE_ENHANCE_MORE) # 滤镜,边界加强(阈值更大)
 
 return img, strs
 
 
def create_lines(draw,n_line,width,height):
 '''绘制干扰线'''
 line_num = random.randint(n_line[0],n_line[1]) # 干扰线条数
 for i in range(line_num):
  # 起始点
  begin = (random.randint(0, width), random.randint(0, height))
  #结束点
  end = (random.randint(0, width), random.randint(0, height))
  draw.line([begin, end], fill=(0, 0, 0))
 
def create_points(draw,point_chance,width,height):
 '''绘制干扰点'''
 chance = min(100, max(0, int(point_chance))) # 大小限制在[0, 100]
  
 for w in xrange(width):
  for h in xrange(height):
   tmp = random.randint(0, 100)
   if tmp > 100 - chance:
    draw.point((w, h), fill=(0, 0, 0))
 
def create_strs(draw,chars,length,font_type, font_size,width,height,fg_color):
 '''绘制验证码字符'''
 '''生成给定长度的字符串,返回列表格式'''
 c_chars = random.sample(chars, length)
 strs = ' %s ' % ' '.join(c_chars) # 每个字符前后以空格隔开
  
 font = ImageFont.truetype(font_type, font_size)
 font_width, font_height = font.getsize(strs)
 
 draw.text(((width - font_width) / 3, (height - font_height) / 3),strs, font=font, fill=fg_color)
  
 return ''.join(c_chars)
 
 
if __name__ == "__main__":
  code_img = create_validate_code()
  code_img[0].save("validate.gif", "GIF")
  print code_img[1]
Python 相关文章推荐
python实现比较两段文本不同之处的方法
May 30 Python
Python实现保证只能运行一个脚本实例
Jun 24 Python
利用Python查看目录中的文件示例详解
Aug 28 Python
Python 获得命令行参数的方法(推荐)
Jan 24 Python
Python内存读写操作示例
Jul 18 Python
python 读取修改pcap包的例子
Jul 23 Python
python issubclass 和 isinstance函数
Jul 25 Python
python实现抠图给证件照换背景源码
Aug 20 Python
Python如何使用BeautifulSoup爬取网页信息
Nov 26 Python
Python ORM编程基础示例
Feb 02 Python
keras绘制acc和loss曲线图实例
Jun 15 Python
Python 用__new__方法实现单例的操作
Dec 11 Python
使用Python制作获取网站目录的图形化程序
May 04 #Python
使用Python脚本来获取Cisco设备信息的示例
May 04 #Python
用Python脚本来删除指定容量以上的文件的教程
May 04 #Python
编写Python脚本来获取Google搜索结果的示例
May 04 #Python
编写Python脚本来实现最简单的FTP下载的教程
May 04 #Python
Python下线程之间的共享和释放示例
May 04 #Python
简单介绍Python中利用生成器实现的并发编程
May 04 #Python
You might like
php关于array_multisort多维数组排序的使用说明
2011/01/04 PHP
php采集中国代理服务器网的方法
2015/06/16 PHP
PHPStrom中实用的功能和快捷键大全
2015/09/23 PHP
js判断输入是否为正整数、浮点数等数字的函数代码
2010/11/17 Javascript
图片延迟加载的实现代码(模仿懒惰)
2013/03/29 Javascript
javascript-简单的日历实现及Date对象语法介绍(附图)
2013/05/30 Javascript
jquery统计复选框选中示例
2013/11/05 Javascript
网页广告中JS代码的信息监听示例
2014/04/02 Javascript
jQuery实现TAB选项卡切换特效简单演示
2016/03/04 Javascript
jQuery实现图片轮播效果代码
2016/09/27 Javascript
jQuery基于ajax操作json数据简单示例
2017/01/05 Javascript
ES6中参数的默认值语法介绍
2017/05/03 Javascript
浅谈JavaScript 声明提升
2020/09/14 Javascript
nuxt静态部署打包相对路径操作
2020/11/06 Javascript
python数据结构之二叉树的建立实例
2014/04/29 Python
用Python实现一个简单的多线程TCP服务器的教程
2015/05/05 Python
Python利用Beautiful Soup模块修改内容方法示例
2017/03/27 Python
Python实现的tcp端口检测操作示例
2018/07/24 Python
Python求两个圆的交点坐标或三个圆的交点坐标方法
2018/11/07 Python
对web.py设置favicon.ico的方法详解
2018/12/04 Python
在Python中Dataframe通过print输出多行时显示省略号的实例
2018/12/22 Python
python 实现图片旋转 上下左右 180度旋转的示例
2019/01/24 Python
python 实现识别图片上的数字
2019/07/30 Python
Python封装成可带参数的EXE安装包实例
2019/08/24 Python
在Django下创建项目以及设置settings.py教程
2019/12/03 Python
python+selenium定时爬取丁香园的新型冠状病毒数据并制作出类似的地图(部署到云服务器)
2020/02/09 Python
Python中格式化字符串的四种实现
2020/05/26 Python
Giglio德国网上精品店:奢侈品服装和配件
2016/09/23 全球购物
英国家用电器购物网站:Hughes
2018/02/23 全球购物
工作自我评价分享
2013/12/01 职场文书
周年庆典邀请函范文
2014/01/24 职场文书
道德模范先进事迹
2014/02/14 职场文书
室内设计专业自荐信
2014/05/31 职场文书
运动会闭幕式通讯稿
2015/07/18 职场文书
python执行js代码的方法
2021/05/13 Python
Mysql Innodb存储引擎之索引与算法
2022/02/15 MySQL