zoukankan      html  css  js  c++  java
  • 图形验证码及验证码的动态刷新

    下列代码都是以自己的项目实例讲述的,相关的文本内容很少,主要说明全在代码注释中

    自制图形验证码  

      这里所说的图形验证码都是自制的图形,通过画布、画笔、画笔字体的颜色绘制而成的。将验证码封装成一个类比较好管理,代码里有绝对详细的注释,当然大家可以直接复制。

    里面涉及的字体都是从系统电脑上自带的,大家直接复制当前目录下就可以了。

    主目录/utils/captcha/__init__.py
    
    import random
    import string
    
    # Image:一个画布
    # ImageDraw:一个画笔
    # ImageFont:画笔的字体
    from PIL import Image, ImageDraw, ImageFont
    
    
    # Captcha验证码
    class Captcha(object):
        # 生成4位数的验证码
        numbers = 4
        # 验证码图片的宽度和高度
        size = (100, 30)
        # 验证码字体大小
        fontsize = 25
        # 加入干扰线的条数
        line_number = 2
    
        # 构建一个验证码源文本
        SOURCE = list(string.ascii_letters)
        for index in range(0, 10):
            SOURCE.append(str(index))
    
        # 用来绘制干扰线
        @classmethod
        def __gene_line(cls, draw, width, height):
            begin = (random.randint(0, width), random.randint(0, height))
            end = (random.randint(0, width), random.randint(0, height))
            draw.line([begin, end], fill=cls.__gene_random_color(), width=2)
    
        # 用来绘制干扰点
        @classmethod
        def __gene_points(cls, draw, point_chance, width, height):
            # 大小限在【0, 100】中
            chance = min(100, max(0, int(point_chance)))
            for w in range(width):
                for h in range(height):
                    tmp = random.randint(0, 100)
                    if tmp > 100 - chance:
                        draw.point((w, h), fill=cls.__gene_random_color())
    
        # 生成随机颜色
        @classmethod
        def __gene_random_color(cls, start=0, end=255):
            random.seed()
            return (random.randint(start, end),
                    random.randint(start, end),
                    random.randint(start, end))
    
        # 随机选择一个字体
        @classmethod
        def __gene_random_font(cls):
            fonts = [
                "PAPYRUS.TTF",
                "CENTAUR.TTF",
                "Inkfree.ttf",
                "verdana.ttf",
            ]
            font = random.choice(fonts)
            return "utils/captcha/"+font
    
        # 用来随机生成一个字符串(包括英文和数字)
        @classmethod
        def gene_text(cls, numbers):
            # numbers是生成验证码的位数
            return " ".join(random.sample(cls.SOURCE, numbers))
    
        # 生成验证码
        @classmethod
        def gene_graph_captcha(cls):
            # 验证码图片的宽高
            width, height = cls.size
            # 创建图片
            image = Image.new("RGBA", (width, height), cls.__gene_random_color(0, 100))
            # 验证码的字体
            font = ImageFont.truetype(cls.__gene_random_font(), cls.fontsize)
            # 创建画笔
            draw = ImageDraw.Draw(image)
            # 生成字符串
            text = cls.gene_text(cls.numbers)
            # 获取字体的尺寸
            font_width, font_height = font.getsize(text)
            # 填充字符串
            draw.text(((width-font_width)/2, (height-font_height)/2),
                      text, font=font, fill=cls.__gene_random_color(150, 255))
            # 绘制干扰线
            for x in range(0, cls.line_number):
                cls.__gene_line(draw, width, height)
            # 绘制干扰点
            cls.__gene_points(draw, 10, width, height)
            with open("captcha.png", "wb") as fp:
                image.save(fp)
            return text, image

    显示图形验证码

      一般图形验证码都是在表单中,这样短时间内的数据及建议保存在redis缓存中(用户点击动态刷新图形验证码)。首先我们绘制图形验证码保存到项目的目录下(入口文件是主目录(项目目录)app.py文件,图片也保存到主目录下),然后通过url地址访问自制的图形验证码(这里我只添加主要的代码)

    主目录/common/views.py
    
    @bp.route("/captcha")
    def graph_captcha():
        """
        使用定义好的图形验证码类,来制作验证码
        以验证码为键、验证码为值(为了用户的体验,让其忽略大小写)存储在redis缓存中
        通过BytesIO字节流的方式保存和访问图片
        :return: 图片响应
        """
        # 获取验证码
        text, image = Captcha.gene_graph_captcha()
        cpcache.set(text.lower(), text.lower())
    
        # BytesIO:字节流
        out = BytesIO()
        # 保存图片
        image.save(out, "png")
        # 存储完图片,将文件的指针指向文件头,使下次保存图片能覆盖前面保存的图片,节省空间
        out.seek(0)
        # 访问图片,并将其作为一个响应返回给前台
        resp = make_response(out.read())
        resp.content_type = "image/png"
        return resp

    前端页面的代码如下:

    <div class="form-group">
        <div class="input-group">
            <input type="text" class="form-control" name="graph_captcha" placeholder="图形验证码">
            <span class="input-group-addon captcha-addon">
                <img id="captcha-img" class="captcha-img" src="{{ url_for("common.graph_captcha") }}" alt="">
            </span>
        </div>
    </div>

    动态刷新验证码

      无非就是再生成一张图形验证码,通过url再次访问就可以,但是这样做是非常麻烦的,这里我很难解释(很难!!!),大家就直接复制代码吧,这个代码就是点击图片生成一个新的url访问图片

    这个文件放在公共的目录下就可以了
    
    var cpparam = {
        setParam: function(href, key, value){
            //重新加载整个页面
            var isReplaced = false;
            var urlArray = href.split("?");
            if(urlArray.length > 1){
                var queryArray = urlArray[1].split("&");
                for(var i=0; i < queryArray.length; i++){
                    var paramArray = queryArray[i].split("=");
                    if(paramArray[0] == key){
                        paramArray[1] = value;
                        queryArray[i] = paramArray.join("=");
                        isReplaced = true;
                        break;
                    }
                }
                if(!isReplaced){
                    var params = {};
                    params[key] = value;
                    if(urlArray.length > 1){
                        href = href + "$" + $.param(params);
                    }else{
                        href = href + "?" + $.param(params);
                    }
                }else{
                    var params = queryArray.join("&");
                    urlArray[1] = params;
                    href = urlArray.join("?");
                }
            }else{
                var param = {};
                param[key] = value;
                if(urlArray.length > 1){
                    href = href + "$" + $.param(param);
                }else{
                    href = href + "?" + $.param(param);
                }
            }
            return href;
        }
    };

      对应html的js文件就需要实现元素(图片)点击刷新图片,调用上面的变量cpparam生成一章图片并访问。

    $(function(){
       $("#captcha-img").on("click", function(){
           var self = $(this);
           var src = self.attr("src");
           var newsrc = cpparam.setParam(src, "xx", Math.random());
           self.attr("src", newsrc);
       });
    });
  • 相关阅读:
    Oracle数据库不能使用索引的原因定位
    C语言中的strncmp
    C标准库函数
    C语言字符串函数大全
    Postgres性能检测
    test cert by python
    如何在C语言中巧用正则表达式
    北大软微一年ABCD
    C 语言字符数组的定义与初始化
    25个设计设计灵感的紫色网站案例
  • 原文地址:https://www.cnblogs.com/aitiknowledge/p/11669098.html
Copyright © 2011-2022 走看看