环境准备
python3.52
pycharm5.05
Pillow
自制的验证码工具包/utils/check_code
验证码的作用
防恶意破解密码:防止,使用程序或机器人恶意去试密码.为了提高用户的体验,用户输入错误以后,才会要求输入验证码.
防论坛灌水:这个是很常见的。有一种程序叫做顶帖机,如果无限制的刷,整个论坛可能到处是拉圾信息,比如,百度贴吧,你只要是新用户或者刚刚关注的贴吧,要是发帖,会马上出现验证码。
有效防止注册,以防,使用程序或机器人去无限制注册账号.
防刷票,网上有很多投票类的网站.
2.验证码的原理
验证码于服务器端生成,发送给客户端,并以图像格式显示。客户端提交所显示的验证码,客户端接收并进行比较,若比对失败则不能实现登录或注册,反之成功后跳转相应界面。
实现
生成验证码
点击可刷新
代码:
注意: 配置setting.py ; 创建数据库!
/utils/check_code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import random
from PIL 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))
def create_validate_code(size = ( 120 , 30 ),
chars = init_chars,
img_type = "GIF" ,
mode = "RGB" ,
bg_color = ( 238 , 99 , 99 ),
fg_color = ( 0 , 0 , 255 ),
font_size = 18 ,
font_type = "Monaco.ttf" ,
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) # 创建画笔
def get_chars():
"""生成给定长度的字符串,返回列表格式"""
return random.sample(chars, length)
def create_lines():
"""绘制干扰线"""
line_num = random.randint( * n_line) # 干扰线条数
for i in range (line_num):
# 起始点
begin = (random.randint( 0 , size[ 0 ]), random.randint( 0 , size[ 1 ]))
# 结束点
end = (random.randint( 0 , size[ 0 ]), random.randint( 0 , size[ 1 ]))
draw.line([begin, end], fill = ( 0 , 0 , 0 ))
def create_points():
"""绘制干扰点"""
chance = min ( 100 , max ( 0 , int (point_chance))) # 大小限制在[0, 100]
for w in range (width):
for h in range (height):
tmp = random.randint( 0 , 100 )
if tmp > 100 - chance:
draw.point((w, h), fill = ( 0 , 0 , 0 ))
def create_strs():
"""绘制验证码字符"""
c_chars = get_chars()
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 draw_lines:
create_lines()
if draw_points:
create_points()
strs = create_strs()
# 图形扭曲参数
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
|
urls.py
1
2
3
4
5
6
7
8
|
from django.conf.urls import url
from django.contrib import admin
from web import views
urlpatterns = [
url(r '^admin/' , admin.site.urls),
url(r '^yzhome.html' ,views.yz_home ),
url(r '^yanzheng.html' ,views.yanzheng ),
]
|
views.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
from django.shortcuts import render
from django.shortcuts import HttpResponse
from utils.check_code import create_validate_code
from django.shortcuts import redirect
from io import BytesIO
# Create your views here.
def yz_home(requset):
if requset.method = = 'GET' :
return render(requset, 'yz_home.html' )
else :
return HttpResponse( 'ok' )
def yanzheng(requset):
f = BytesIO()
img,code = create_validate_code()
requset.session[ 'check_code' ] = code
img.save(f, 'PNG' )
return HttpResponse(f.getvalue())
|
/templates/yz_home.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
<!DOCTYPE html>
< html lang = "en" >
< head >
< meta charset = "UTF-8" >
< title >验证码</ title >
</ head >
< body >
< form action = "yz_home.html" method = "POST" >
< div > 用户名:< input type = "text" placeholder = "用户名" name = "username" ></ div >
< div >密码:< input type = "password" placeholder = "密码" name = "pwa" ></ div >
< div >验证码:< input type = "text" name = "yzm" ></ div >
< img src = "/yanzheng.html" onclick = "shuaxin(this);" >
< div >< input type = "submit" value = "确认" ></ div >
< script src = "/static/js/jquery-1.12.4.js" >
</ script >
< script >
function shuaxin(ths){
{# ths.src = ths.src + "?"#}
var i =$(ths).prop("src")
$(ths).prop("src",i+"?")
}
</ script >
</ form >
</ body >
</ html >
|
效果图
知识点总结:
1
2
3
4
5
6
|
< img src = "/yanzheng.html" onclick = "shuaxin(this);" >
< script >
function shuaxin(ths){
ths.src = ths.src + "?"
}
</ script >
|
=
1
2
3
4
5
6
7
8
9
10
|
< img src = "/yanzheng.html" onclick = "shuaxin(this);" >
< script src = "/static/js/jquery-1.12.4.js" >
</ script >
< script >
function shuaxin(ths){
var i =$(ths).prop("src")
$(ths).prop("src",i+"?")
}
</ script >
|
jQueryObject.prop( propertyName [, value ] )
设置或返回指定属性propertyName的值。如果指定了value参数,则表示设置属性propertyName的值为value;如果没有指定value参数,则表示返回属性propertyName的值。
总结
以上就是本文关于Django 生成登陆验证码代码分享的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!
原文链接:http://blog.csdn.net/vastli/article/details/68937260