验证码原理与Django实现--简单图片验证码

前言

在网页中常见图片中包含数字字母的验证码如下如果将其简化,那么我们可以认为验证码是由数字字母加上遮挡的线段所构成。本文,我们不妨先解决其中数字与字母的简单生成


数字字母的生成原理与代码实现

 首先,可以使用PIL库中的类Image和ImageDraw,用于生成图片和调用画笔对生成的图片进行修改。需要下载pillow库,导入时则为PIL

pip3.8 install pillow

选择好字体以及大小,就可以开始使用循环随机生成字母数字了,将每次生成的数字或字母拼接起来就组成了完整的验证码,再将其保存到session中,用于后续判断,最后使用io库中的BytesIO类临时保存该图片并将读取的图片返回。具体实现如下:

from io import BytesIO
from django.shortcuts import HttpResponse, render
from PIL import Image, ImageFont, ImageDraw

def num_code(request):
    # 创建一个图片
    img_obj = Image.new('RGB', (500, 200), color='white')
    # 实例化画笔
    img_draw = ImageDraw.Draw(img_obj)
    # 设置字体样式, 字体大小
    img_font = ImageFont.truetype('static/font/font_1.ttf', 50)
    # 验证码
    code = ''
    for i in range(5):
        # 随机生成
        random_upper = chr(random.randint(65, 90))  # 大写字母
        random_lower = chr(random.randint(97, 122))  # 小写字母
        random_int = str(random.randint(0, 9))  # 数字
        # 随机选择
        temp = random.choice([random_int, random_upper, random_lower])
        # 在图片上生成该验证码
        img_draw.text(xy=((i + 1) * 80, 75), text=temp, font=img_font, fill='black')
        code += temp

    # 将验证码存储在会话中
    request.session['captcha_code'] = code
    # 使用BytesIO进行临时存储
    io_obj = BytesIO()
    img_obj.save(io_obj, 'png')
    # 返回图片
    return HttpResponse(io_obj.getvalue())

前端页面的展示

前端页面主要是将img的路径表达正确,实现点击图片刷新的效果,实现如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>验证码</title>
    {% load static %}
    <link rel="stylesheet" href="{% static 'bootstrap-3.4.1-dist/css/bootstrap.min.css' %}">
    <script src="{% static 'js/jquery-3.6.0.min.js' %}"></script>
    <script src="{% static 'bootstrap-3.4.1-dist/js/bootstrap.min.js' %}"></script>
</head>
<body>
    <h1 style="text-align: center">验证码</h1>
    <div style="text-align: center;height: 300px;">
{#        路径表达#}
        <img src="/picture/{{ location }}/" id="id_img">
    </div>
    <form method="post">
        <div class="container">
            <div class="row justify-content-center">
                <div>
                    <div class="input-group" style="text-align: center">
                        <input type="text" class="form-control" placeholder="请输入验证码" id="id_code" name="input_code">
                        <span class="input-group-btn">
                            <button class="btn btn-default" type="submit" id="id_confirm">确认</button>
                        </span>
                    </div><!-- /input-group -->
                </div>
            </div><!-- /.row -->
        </div>
    </form>
    <script>
        // 点击实现验证码刷新
        $('#id_img').click(function () {
            let time = new Date().getTime();
            $(this).attr('src', '/picture/{{ location }}/?' + time) ;
            // 或者更简单的:
            // $(this).attr('src', $(this).attr('src') + '?') ;
        })
    </script>
</body>
</html>

 界面展示:


后端对提交验证码的判断

 其实对验证码的判断并不难,而是想到if request.method == 'POST':达到一个分流的效果

def number_check(request, location):
    # 这个判断可以对访问起到分辨作用,即只有点击确认后才会进行获取并判断
    if request.method == 'POST':
        # 获取输入的验证码并进行判断
        input_code = str(request.POST.get('input_code'))
        store_code = request.session.get('captcha_code')
        # 不区分大小写
        if input_code.lower() == store_code.lower():
            return HttpResponse('验证码正确')
        else:
            return HttpResponse('验证码错误')
    return render(request, 'base.html', locals())

总结

原理并不难,较难的地方在于实操时能否将其综合起来

不足请指正

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值