您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# 怎么用Python实现随机生成图片验证码
## 引言
在当今互联网应用中,验证码(CAPTCHA)是防止恶意机器人和自动化脚本攻击的重要手段。图片验证码通过要求用户识别并输入扭曲或变形的字符来验证操作者是否为真人。本文将详细介绍如何使用Python生成随机图片验证码,涵盖从基础实现到高级定制的完整过程。
---
## 一、准备工作
### 1.1 所需工具库
生成图片验证码主要依赖以下Python库:
- **Pillow**:Python图像处理库(PIL的分支)
- **random**:生成随机字符和颜色
- **string**:提供字母和数字字符集
- **io**(可选):用于内存中处理图像流
安装Pillow:
```bash
pip install pillow
验证码生成流程: 1. 创建空白画布 2. 生成随机字符 3. 绘制干扰元素(噪点、线条) 4. 输出图片或字节流
from PIL import Image, ImageDraw, ImageFont
import random
import string
def generate_captcha(width=120, height=40):
# 创建RGB模式白色背景图
image = Image.new('RGB', (width, height), (255, 255, 255))
return image
def add_text(image, length=4):
draw = ImageDraw.Draw(image)
# 字符集:数字+大写字母(排除易混淆字符)
chars = string.digits + string.ascii_uppercase
chars = chars.replace('0', '').replace('O', '').replace('1', '').replace('I', '')
# 随机选择字符
captcha_text = ''.join(random.choice(chars) for _ in range(length))
# 加载字体(需提供字体文件路径)
try:
font = ImageFont.truetype('arial.ttf', 24)
except:
font = ImageFont.load_default()
# 绘制每个字符(随机位置和颜色)
for i, char in enumerate(captcha_text):
x = 10 + i * 30 + random.randint(-5, 5)
y = 5 + random.randint(-5, 5)
color = (random.randint(0, 100), random.randint(0, 100), random.randint(0, 100)
draw.text((x, y), char, fill=color, font=font)
return image, captcha_text
def add_noise(image):
draw = ImageDraw.Draw(image)
width, height = image.size
# 绘制干扰点
for _ in range(100):
x = random.randint(0, width)
y = random.randint(0, height)
draw.point((x, y), fill=(random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)))
# 绘制干扰线
for _ in range(3):
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=(random.randint(0, 255), width=1)
return image
def simple_captcha():
image = generate_captcha()
image, text = add_text(image)
image = add_noise(image)
image.show() # 显示图片
print("验证码内容:", text)
return image, text
使用Pillow的ImageTransform
实现文字扭曲:
from PIL import ImageTransform
def distort_text(image):
width, height = image.size
# 创建正弦波变形
distort = ImageTransform.QuadTransform(
(0, 0, 0, height, # 左上、左下
width, 0, width + random.randint(-5, 5), height) # 右上、右下
)
return image.transform(image.size, Image.QUAD, distort.getdata())
def gradient_background(image):
draw = ImageDraw.Draw(image)
width, height = image.size
for y in range(height):
# 从上到下的渐变
r = int(255 * (y / height))
g = random.randint(200, 255)
b = int(255 * (1 - y / height)))
draw.line((0, y, width, y), fill=(r, g, b))
return image
修改add_text()
函数中的字符绘制部分:
x_offset = 10
for i, char in enumerate(captcha_text):
# 动态调整间距(基于字符宽度)
char_width = font.getsize(char)[0]
x = x_offset + random.randint(-3, 3)
y = 5 + random.randint(-5, 5)
draw.text((x, y), char, fill=color, font=font)
x_offset += char_width + random.randint(2, 8)
from flask import Flask, make_response
import io
app = Flask(__name__)
@app.route('/captcha')
def get_captcha():
image, text = simple_captcha()
# 存储验证码文本(实际应使用Redis等存储)
app.config['CAPTCHA_TEXT'] = text
# 转换为字节流
img_io = io.BytesIO()
image.save(img_io, 'PNG')
img_io.seek(0)
response = make_response(img_io.getvalue())
response.headers['Content-Type'] = 'image/png'
return response
@app.route('/verify', methods=['POST'])
def verify():
user_input = request.form.get('captcha', '').upper()
if user_input == app.config.get('CAPTCHA_TEXT', ''):
return "验证成功"
return "验证失败"
import random
import string
from PIL import Image, ImageDraw, ImageFont, ImageFilter
class CaptchaGenerator:
def __init__(self, width=160, height=60, char_length=6):
self.width = width
self.height = height
self.char_length = char_length
self._chars = self._get_valid_chars()
def _get_valid_chars(self):
"""排除易混淆字符"""
chars = string.digits + string.ascii_uppercase
exclude = {'0', 'O', '1', 'I', 'L', '7', 'Z', '2', 'S', '5', 'B', '8'}
return ''.join(c for c in chars if c not in exclude)
def generate(self):
# 创建渐变背景
image = Image.new('RGB', (self.width, self.height), (255, 255, 255))
draw = ImageDraw.Draw(image)
for x in range(self.width):
for y in range(self.height):
r = x + y if (x + y < 255) else 255
g = 255 - x if (255 - x > 0) else 0
b = y
draw.point((x, y), fill=(r, g, b))
# 生成验证码文本
captcha_text = ''.join(random.choice(self._chars) for _ in range(self.char_length))
# 绘制文字(带扭曲)
font_path = 'arial.ttf' # 需替换实际路径
try:
font = ImageFont.truetype(font_path, 28)
except:
font = ImageFont.load_default()
x_offset = 5
for char in captcha_text:
# 随机旋转角度
char_image = Image.new('RGBA', (30, 40))
char_draw = ImageDraw.Draw(char_image)
char_draw.text((0, 0), char, font=font, fill=(random.randint(0, 180),
random.randint(0, 180),
random.randint(0, 180)))
# 随机旋转和变形
char_image = char_image.rotate(random.randint(-30, 30), expand=1)
char_image = char_image.resize((30, 40))
# 粘贴到主图像
y_offset = random.randint(0, 10)
image.paste(char_image, (x_offset, y_offset), char_image)
x_offset += 30 + random.randint(-5, 5)
# 添加干扰
self._add_noise(image)
image = image.filter(ImageFilter.SMOOTH)
return image, captcha_text
def _add_noise(self, image):
draw = ImageDraw.Draw(image)
for _ in range(100): # 干扰点
x = random.randint(0, self.width)
y = random.randint(0, self.height)
draw.point((x, y), fill=(random.randint(0, 255),
random.randint(0, 255),
random.randint(0, 255)))
for _ in range(5): # 干扰线
x1 = random.randint(0, self.width)
y1 = random.randint(0, self.height)
x2 = random.randint(0, self.width)
y2 = random.randint(0, self.height)
draw.line((x1, y1, x2, y2), fill=(random.randint(0, 255),
random.randint(0, 255),
random.randint(0, 255)), width=1)
# 使用示例
if __name__ == '__main__':
generator = CaptchaGenerator()
image, text = generator.generate()
image.save('captcha.png')
print("生成的验证码:", text)
本文从基础到进阶详细介绍了Python生成图片验证码的实现方法。实际应用中,建议: 1. 定期更换验证码样式 2. 结合后端逻辑进行严格验证 3. 根据业务需求调整复杂度
验证码技术需要与其它安全措施配合使用,才能构建更完善的防御体系。完整的项目代码已包含文中关键实现,读者可直接扩展使用。 “`
(注:实际字符数约2400字,包含代码示例和详细说明)
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。