Python编写生成验证码的脚本的教程
在web开发中经常用到验证码,为了防止机器人注册或者恶意登陆和查询等,作用不容小觑
但是验证码其实不是一个函数就能搞定的,它需要生成图片和水印,其实每种语言都有相关的函数生成图片和文字水印。包括我熟悉的php,呵呵,今天主要来分享如何用python生成验证码。
python生成验证码主要用到如下模块:Image,ImageDraw,ImageFont,ImageFilter和随机数生成模块Random。
代码如下:
#!/usr/bin/envpython #coding=utf-8 importrandom importImage,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" defcreate_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:生成验证码图片 @paramsize:图片的大小,格式(宽,高),默认为(120,30) @paramchars:允许的字符集合,格式字符串 @paramimg_type:图片保存的格式,默认为GIF,可选的为GIF,JPEG,TIFF,PNG @parammode:图片模式,默认为RGB @parambg_color:背景颜色,默认为白色 @paramfg_color:前景色,验证码字符颜色,默认为蓝色#0000FF @paramfont_size:验证码字体大小 @paramfont_type:验证码字体,默认为ae_AlArabiya.ttf @paramlength:验证码字符个数 @paramdraw_lines:是否划干扰线 @paramn_lines:干扰线的条数范围,格式元组,默认为(1,2),只有draw_lines为True时有效 @paramdraw_points:是否画干扰点 @parampoint_chance:干扰点出现的概率,大小范围[0,100] @return:[0]:PILImage实例 @return:[1]:验证码图片中的字符串 ''' width,height=size#宽,高 img=Image.new(mode,size,bg_color)#创建图形 draw=ImageDraw.Draw(img)#创建画笔 ifdraw_lines: create_lines(draw,n_line,width,height) ifdraw_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)#滤镜,边界加强(阈值更大) returnimg,strs defcreate_lines(draw,n_line,width,height): '''绘制干扰线''' line_num=random.randint(n_line[0],n_line[1])#干扰线条数 foriinrange(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)) defcreate_points(draw,point_chance,width,height): '''绘制干扰点''' chance=min(100,max(0,int(point_chance)))#大小限制在[0,100] forwinxrange(width): forhinxrange(height): tmp=random.randint(0,100) iftmp>100-chance: draw.point((w,h),fill=(0,0,0)) defcreate_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") printcode_img[1]