zoukankan      html  css  js  c++  java
  • 随机验证码

    Python生成随机验证码,需要使用PIL模块.python3则是pillow

    安装:

    1
    pip3 install pillow

    基本使用

    1. 创建图片

    1
    2
    3
    4
    5
    6
    7
    8
    9
    from PIL import Image
    img = Image.new(mode='RGB', size=(120, 30), color=(255, 255, 255))
      
    # 在图片查看器中打开
    # img.show()
      
    # 保存在本地
    with open('code.png','wb') as f:
        img.save(f,format='png')

    2. 创建画笔,用于在图片上画任意内容

    1
    2
    img = Image.new(mode='RGB', size=(120, 30), color=(255, 255, 255))
    draw = ImageDraw.Draw(img, mode='RGB')

    3. 画点

    1
    2
    3
    4
    5
    6
    img = Image.new(mode='RGB', size=(120, 30), color=(255, 255, 255))
    draw = ImageDraw.Draw(img, mode='RGB')
    # 第一个参数:表示坐标
    # 第二个参数:表示颜色
    draw.point([100, 100], fill="red")
    draw.point([300, 300], fill=(255, 255, 255))

    4. 画线

    1
    2
    3
    4
    5
    6
    img = Image.new(mode='RGB', size=(120, 30), color=(255, 255, 255))
    draw = ImageDraw.Draw(img, mode='RGB')
    # 第一个参数:表示起始坐标和结束坐标
    # 第二个参数:表示颜色
    draw.line((100,100,100,300), fill='red')
    draw.line((100,100,300,100), fill=(255, 255, 255))

    5. 画圆

    1
    2
    3
    4
    5
    6
    7
    img = Image.new(mode='RGB', size=(120, 30), color=(255, 255, 255))
    draw = ImageDraw.Draw(img, mode='RGB')
    # 第一个参数:表示起始坐标和结束坐标(圆要画在其中间)
    # 第二个参数:表示开始角度
    # 第三个参数:表示结束角度
    # 第四个参数:表示颜色
    draw.arc((100,100,300,300),0,90,fill="red")

    6. 写文本

    1
    2
    3
    4
    5
    6
    img = Image.new(mode='RGB', size=(120, 30), color=(255, 255, 255))
    draw = ImageDraw.Draw(img, mode='RGB')
    # 第一个参数:表示起始坐标
    # 第二个参数:表示写入内容
    # 第三个参数:表示颜色
    draw.text([0,0],'python',"red")

    7. 特殊字体文字

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    img = Image.new(mode='RGB', size=(120, 30), color=(255, 255, 255))
    draw = ImageDraw.Draw(img, mode='RGB')
    # 第一个参数:表示字体文件路径
    # 第二个参数:表示字体大小
    font = ImageFont.truetype("kumo.ttf", 28)
    # 第一个参数:表示起始坐标
    # 第二个参数:表示写入内容
    # 第三个参数:表示颜色
    # 第四个参数:表示颜色
    draw.text([0, 0], 'python', "red", font=font)

    图片验证码

    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
    import random
      
    def check_code(width=120, height=30, char_length=5, font_file='kumo.ttf', font_size=28):
        code = []
        img = Image.new(mode='RGB', size=(width, height), color=(255, 255, 255))
        draw = ImageDraw.Draw(img, mode='RGB')
      
        def rndChar():
            """
            生成随机字母  
            :return:
            """
            return chr(random.randint(65, 90))
      
        def rndColor():
            """
            生成随机颜色
            :return:
            """
            return (random.randint(0, 255), random.randint(10, 255), random.randint(64, 255))
      
        # 写文字
        font = ImageFont.truetype(font_file, font_size)
        for i in range(char_length):
            char = rndChar()
            code.append(char)
            h = random.randint(0, 4)
            draw.text([i * width / char_length, h], char, font=font, fill=rndColor())
      
        # 写干扰点
        for i in range(40):
            draw.point([random.randint(0, width), random.randint(0, height)], fill=rndColor())
      
        # 写干扰圆圈
        for i in range(40):
            draw.point([random.randint(0, width), random.randint(0, height)], fill=rndColor())
            x = random.randint(0, width)
            y = random.randint(0, height)
            draw.arc((x, y, x + 4, y + 4), 0, 90, fill=rndColor())
      
        # 画干扰线
        for i in range(5):
            x1 = random.randint(0, width)
            y1 = random.randint(0, height)
            x2 = random.randint(0, width)
            y2 = random.randint(0, height)
      
            draw.line((x1, y1, x2, y2), fill=rndColor())
      
        img = img.filter(ImageFilter.EDGE_ENHANCE_MORE)
        return img,''.join(code)
      
      
    if __name__ == '__main__':
        # 1. 直接打开
        # img,code = check_code()
        # img.show()
      
        # 2. 写入文件
        # img,code = check_code()
        # with open('code.png','wb') as f:
        #     img.save(f,format='png')
      
        # 3. 写入内存(Python3)
        # from io import BytesIO
        # stream = BytesIO()
        # img.save(stream, 'png')
        # stream.getvalue()
      
        # 4. 写入内存(Python2)
        # import StringIO
        # stream = StringIO.StringIO()
        # img.save(stream, 'png')
        # stream.getvalue()
      
        pass

      

      

     

    def validcode(request):
        import random
        from PIL import Image, ImageDraw, ImageFont
        from io import BytesIO
    
        img = Image.new(mode='RGB', size=(120, 40),
                        color=(random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)))
        draw = ImageDraw.Draw(img, 'RGB')
        font = ImageFont.truetype('app01/static/font/kumo.ttf', 25)
        valid_list = []
        for i in range(5):
            random_num = str(random.randint(0, 9))
            random_upper_alp = chr(random.randint(65, 90))
            random_lower_alp = chr(random.randint(97, 122))
            valid_ele = random.choice([random_num, random_upper_alp, random_lower_alp])
            valid_list.append(valid_ele)
            draw.text([5 + i * 24, 10], valid_ele, (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)),
                      font=font)
    
            # 写干扰点
        for i in range(40):
            draw.point([random.randint(0, 120), random.randint(0, 40)],
                       fill=(random.randint(0, 255), random.randint(10, 255), random.randint(64, 255)))
    
            # 写干扰圆圈
        for i in range(40):
            draw.point([random.randint(0, 120), random.randint(0, 40)],
                       fill=(random.randint(0, 255), random.randint(10, 255), random.randint(64, 255)))
            x = random.randint(0, 120)
            y = random.randint(0, 40)
            draw.arc((x, y, x + 4, y + 4), 0, 90,
                     fill=(random.randint(0, 255), random.randint(10, 255), random.randint(64, 255)))
    
            # 画干扰线
        for i in range(5):
            x1 = random.randint(0, 120)
            y1 = random.randint(0, 40)
            x2 = random.randint(0, 120)
            y2 = random.randint(0, 40)
    
            draw.line((x1, y1, x2, y2), fill=(random.randint(0, 255), random.randint(10, 255), random.randint(64, 255)))
    
        f = BytesIO()
        img.save(f, 'png')
        data = f.getvalue()
        valid_str = ''.join(valid_list)     #将验证码拼接成字符串
        print(valid_str)
        request.session["keepValidCode"] = valid_str   #将验证码保存在session中,方便在登陆时验证
    
    
        return HttpResponse(data)
    def validcode(request):
    from app01 import models
    from django.contrib.auth import authenticate, login, logout
    def log_in(request):
        '''登陆'''
        if request.method == 'GET':
            form = LoginForm()
            return render(request, 'login.html', {'form': form})
        else:
            data = request.POST
            form = LoginForm(data=data)
            validcode = request.POST.get('validcode')
    
            if not form.is_valid():
                return HttpResponse(json.dumps(dict(form.errors)))
            if validcode.upper() != request.session["keepValidCode"].upper():
                return HttpResponse(json.dumps('codeError'))
    
            user = authenticate(**form.cleaned_data)
            # user=models.UserInfo.objects.filter(**form.cleaned_data)
            if not user:
    
                return HttpResponse(json.dumps({'flag': False, 'msg': "用户名或者密码错误"}))
    
            else:
                login(request, user)  #设置session 
            return HttpResponse(json.dumps({'flag': True}))
    def log_in(request):

     

      

      

    img中src实现局部刷新验证码的功能

    html部分:

    1
    2
    3
    4
    5
    6
    7
    <p><label class="lbright">验证码:</label>
    <span>
    <input type="text" name="validcode" style="70px; vertical-align:middle;" id="validcode"/>
    <img id="codePic" src="http://127.0.0.1:8888/TP/codePic" width="60" height="21" style="vertical-align:middle;cursor:pointer;"/>
    </span>
    <a class="blurry" id="newPic" onclick="getPic();">看不清楚,换一张</a>
    </p>

    js部分:

    1
    2
    3
    4
    5
    <script type="text/javascript">
    function getPic(){
    $("#codePic").attr("src","http://127.0.0.1:8888/TP/codePic?flag="+Math.random());
    };
    </script>

    或:

    // 验证码刷新
        $(".validCode_img").click(function () {
            $(this)[0].src+="?"
        })

    这部分最重要的就是 $("#codePic").attr("src","http://127.0.0.1:8888/TP/codePic?flag="+Math.random()); 这部分的代码。如果不加flag="+Math.random()是实现不了局部刷新的功能的。因为src中如果每次访问的地址一样的话就会发生不更新的情况。具体为什么会发生这种情况大家可以自己去研究。而codePic其实是一个action。这个action的功能是利用java画笔画出验证码并打包成图片返回给img中的src。

      

      

     
  • 相关阅读:
    HDU 3951 (博弈) Coin Game
    HDU 3863 (博弈) No Gambling
    HDU 3544 (不平等博弈) Alice's Game
    POJ 3225 (线段树 区间更新) Help with Intervals
    POJ 2528 (线段树 离散化) Mayor's posters
    POJ 3468 (线段树 区间增减) A Simple Problem with Integers
    HDU 1698 (线段树 区间更新) Just a Hook
    POJ (线段树) Who Gets the Most Candies?
    POJ 2828 (线段树 单点更新) Buy Tickets
    HDU 2795 (线段树 单点更新) Billboard
  • 原文地址:https://www.cnblogs.com/huchong/p/7867570.html
Copyright © 2011-2022 走看看