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中set常用操作汇总
Jun 30 Python
python安装oracle扩展及数据库连接方法
Feb 21 Python
python 截取 取出一部分的字符串方法
Mar 01 Python
对numpy中布尔型数组的处理方法详解
Apr 17 Python
python绘制直线的方法
Jun 30 Python
网易有道2017内推编程题 洗牌(python)
Jun 19 Python
Python Pandas分组聚合的实现方法
Jul 02 Python
Django框架模板用法入门教程
Nov 04 Python
python3.6环境下安装freetype库和基本使用方法(推荐)
May 10 Python
python进度条显示-tqmd模块的实现示例
Aug 23 Python
pandas apply使用多列计算生成新的列实现示例
Feb 24 Python
python 逐步回归算法
Apr 06 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的autoload自动加载机制使用说明
2010/12/28 PHP
php获取从百度搜索进入网站的关键词的详细代码
2014/01/08 PHP
PHP反向代理类代码
2014/08/15 PHP
jquery获取多个checkbox的值异步提交给php的方法
2015/06/24 PHP
PHP模板解析类实例
2015/07/09 PHP
php中array_slice和array_splice函数解析
2016/10/18 PHP
PHP判断访客是否手机端(移动端浏览器)访问的方法总结【4种方法】
2019/03/27 PHP
解决AJAX中跨域访问出现'没有权限'的错误
2008/08/20 Javascript
JavaScript统计网站访问次数的实现代码
2015/11/18 Javascript
javascript和jquery实现用户登录验证
2016/05/04 Javascript
jQuery插件fullPage.js实现全屏滚动效果
2016/12/02 Javascript
vue实现模态框的通用写法推荐
2018/02/26 Javascript
浅析JS中什么是自定义react数据验证组件
2018/10/19 Javascript
JavaScript函数定义方法实例详解
2019/03/05 Javascript
angular 实现同步验证器跨字段验证的方法
2019/04/11 Javascript
浅谈vuex为什么不建议在action中修改state
2020/02/02 Javascript
全局安装 Vue cli3 和 继续使用 Vue-cli2.x操作
2020/09/08 Javascript
为什么JavaScript中0.1 + 0.2 != 0.3
2020/12/03 Javascript
在Python中使用模块的教程
2015/04/27 Python
python解决网站的反爬虫策略总结
2016/10/26 Python
numpy数组拼接简单示例
2017/12/15 Python
Python实现求数列和的方法示例
2018/01/12 Python
python微信跳一跳系列之棋子定位像素遍历
2018/02/26 Python
pyinstaller打包opencv和numpy程序运行错误解决
2019/08/16 Python
pandas数据处理进阶详解
2019/10/11 Python
关于tf.TFRecordReader()函数的用法解析
2020/02/17 Python
关于Python错误重试方法总结
2021/01/03 Python
KIKO MILANO西班牙官网:意大利领先的化妆品和护肤品品牌
2019/05/03 全球购物
大专生的学习自我评价
2013/12/04 职场文书
外贸专业求职信
2014/03/09 职场文书
行政管理专业求职信
2014/07/06 职场文书
快递员岗位职责
2014/09/12 职场文书
2015年纪念“卢沟桥事变”78周年活动方案
2015/05/06 职场文书
医院岗前培训心得体会
2016/01/08 职场文书
Go语言并发编程 sync.Once
2021/10/16 Golang
分享mysql的current_timestamp小坑及解决
2021/11/27 MySQL