使用graphic-verification-code庫做一個生成驗證碼的測試
1.概述
圖片驗證碼大部分需要登錄的網站都有實現的一個功能
作用:為了提高系統的安全性有了驗證碼,防止大量重復請求、機器人暴力訪問等情況的。我們就可以要求用戶在輸入用戶名,密碼等信息后,同時輸入圖片上的文字,用戶提交后,系統會首先從session中提取剛剛生成的驗證碼,並和用戶輸入的驗證碼進行比較,如果比較相等,表示用戶是從登錄界面登錄過來的,否則,表示用戶是非法的
2.安裝
sudo pip install graphic-verification-code

3.導入

4.編寫
查看可用方法,方法並不多,所以可以方便快速的查看源碼學習

python版本判斷:2.x還是3.x
# -*- 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.測試


