只需兩行代碼實現圖片驗證碼

使用graphic-verification-code庫作一個生成驗證碼的測試

1.概述

圖片驗證碼大部分須要登陸的網站都有實現的一個功能python

做用:爲了提升系統的安全性有了驗證碼,防止大量重複請求、機器人暴力訪問等狀況的。咱們就能夠要求用戶在輸入用戶名,密碼等信息後,同時輸入圖片上的文字,用戶提交後,系統會首先從session中提取剛剛生成的驗證碼,並和用戶輸入的驗證碼進行比較,若是比較相等,表示用戶是從登陸界面登陸過來的,不然,表示用戶是非法的安全

 

2.安裝

sudo pip install graphic-verification-code

 

3.導入

 

4.編寫

查看可用方法,方法並很少,因此能夠方便快速的查看源碼學習session

python版本判斷:2.x仍是3.xdom

# -*- coding: utf-8 -*-

"""
pythoncompat
"""

import sys


# -------
# Pythons
# -------

# Syntax sugar.
_ver = sys.version_info

#: Python 2.x?
is_py2 = (_ver[0] == 2)

#: Python 3.x?
is_py3 = (_ver[0] == 3)

# ---------
# Specifics
# ---------

if is_py2:
    range = xrange

    builtin_str = str
    bytes = str
    str = unicode
    basestring = basestring
    numeric_types = (int, long, float)

elif is_py3:
    range = range

    builtin_str = str
    str = str
    bytes = bytes
    basestring = (str, bytes)
    numeric_types = (int, float)

主要模塊main學習

# -*- coding: utf-8 -*-

import base64 as b64
import os
import random
from cStringIO import StringIO

from .compat import range


try:
    from PIL import Image, ImageDraw, ImageFilter, ImageFont
except ImportError:
    import Image, ImageDraw, ImageFilter, ImageFont


class GraphicVerificationCode(object):

    def __init__(self):
        self.chars = 'abcdefghjkmnpqrstuvwxyABCDEFGHJKMNPQRSTUVWXY3456789'
        self.BASE_DIR = os.path.dirname(os.path.abspath(__file__))
        self.SRC_DIR = os.path.join(self.BASE_DIR, 'resource')
        self.FONT_DIR = os.path.join(self.SRC_DIR, 'fonts')
        self.FONT_FILE = os.path.join(self.FONT_DIR, 'simsun.ttc')

    def generate(self, size=(120, 30), chars=None, format='PNG', mode='RGB', bg_color=(255, 255, 255), fg_color=(0, 0, 255), font_size=18, font_file=None, length=4, draw_lines=True, line_range=(1, 2), draw_points=True, point_chance=2):

        """
        @param size: 圖片的大小,格式(寬,高),默認爲(120, 30)
        @param chars: 容許的字符集合,格式字符串
        @param format: 圖片保存的格式,默認爲 PNG,可選的爲 GIF,JPEG,TIFF,PNG
        @param mode: 圖片模式,默認爲 RGB
        @param bg_color: 背景顏色,默認爲白色
        @param fg_color: 前景色,驗證碼字符顏色,默認爲藍色 #0000FF
        @param font_size: 驗證碼字體大小
        @param font_file: 驗證碼字體,默認爲 None
        @param length: 驗證碼字符個數
        @param draw_lines: 是否劃干擾線
        @param line_range: 干擾線的條數範圍,格式元組,默認爲 (1, 2),只有 draw_lines 爲 True 時有效
        @param draw_points: 是否畫干擾點
        @param point_chance: 干擾點出現的機率,大小範圍 [0, 100],只有 draw_points 爲 True 時有效
        @return: [0]: PIL Image 實例
        @return: [1]: 驗證碼圖片中的字符串
        """
        width, height = size  # 寬, 高
        im = Image.new(mode, size, bg_color)  # 建立圖形
        draw = ImageDraw.Draw(im)  # 建立畫筆

        def generate_chars():
            """ 生成給定長度的字符串,返回列表格式 """
            return random.sample(chars or self.chars, length)

        def random_dot():
            """ 隨機點 """
            return random.randint(0, width), random.randint(0, height)

        def create_line():
            """ 繪製干擾線 """
            draw.line([random_dot(), random_dot()], fill=(0, 0, 0))

        def create_lines():
            """ 繪製干擾線 """
            line_num = random.randint(*line_range)  # 干擾線條數
            [create_line() for _ in range(line_num)]

        def create_points():
            """ 繪製干擾點 """
            chance = min(100, max(0, int(point_chance)))  # 大小限制在[0, 100]
            [draw.point((w, h), fill=(0, 0, 0)) for w in range(width) for h in range(height) if random.randint(0, 100) < chance]

        def create_chars():
            """ 繪製驗證碼字符 """
            chars = generate_chars()
            strs = ' {0} '.format(' '.join(chars))  # 每一個字符先後以空格隔開

            font = ImageFont.truetype(font_file if os.path.exists(font_file or '') else self.FONT_FILE, font_size)
            font_width, font_height = font.getsize(strs)
            xy = ((width - font_width) / 3, (height - font_height) / 3)
            draw.text(xy, strs, font=font, fill=fg_color)
            return ''.join(chars)

        if draw_lines:
            create_lines()

        if draw_points:
            create_points()

        vcode = create_chars()

        # 圖形扭曲參數
        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]
        im = im.transform(size, Image.PERSPECTIVE, params)  # 建立扭曲
        im = im.filter(ImageFilter.EDGE_ENHANCE_MORE)  # 濾鏡,邊界增強(閾值更大)

        return im, vcode

    def base64(self, format='PNG'):
        im, vcode = self.generate()
        out = StringIO()
        im.save(out, format=format)
        return b64.b64encode(out.getvalue()), vcode


_global_instance = GraphicVerificationCode()
generate = _global_instance.generate
base64 = _global_instance.base64

 

5.測試

相關文章
相關標籤/搜索