当前位置: 首页 > 开发者资讯

python如何编写验证码程序?

  验证码是Web应用中防止自动化攻击的重要手段。下面我将详细介绍如何使用Python实现一个完整的验证码系统,包括生成、验证和安全防护等关键环节。在Flask中集成验证码需存储验证码文本并设置过期时间。前端通过接口获取验证码图片,用户提交后比对输入与存储值。

  python如何编写验证码程序?

  一、基础验证码生成

  1. 使用Pillow库生成图片验证码

  pythonfrom PIL import Image, ImageDraw, ImageFont, ImageFilterimport randomimport stringimport osclass CaptchaGenerator:def __init__(self, width=120, height=40, char_num=4):self.width = widthself.height = heightself.char_num = char_num # 验证码字符数self.chars = string.ascii_letters + string.digits # 字符集def generate_image(self):# 创建空白图像image = Image.new('RGB', (self.width, self.height), (255, 255, 255))draw = ImageDraw.Draw(image)# 生成随机字符captcha_text = ''.join(random.choices(self.chars, k=self.char_num))# 设置字体try:font = ImageFont.truetype('arial.ttf', 24)except:font = ImageFont.load_default()# 绘制字符(添加随机颜色和位置偏移)for i, char in enumerate(captcha_text):draw.text((10 + i * 25 + random.randint(-3, 3), 10 + random.randint(-5, 5)),char,fill=(random.randint(50, 150), random.randint(50, 150), random.randint(50, 150)),font=font)# 添加干扰元素self._add_noise(draw, image)# 添加扭曲效果image = self._warp_image(image)return image, captcha_textdef _add_noise(self, draw, image):# 添加干扰线for _ in range(3):draw.line([(random.randint(0, self.width), random.randint(0, self.height)),(random.randint(0, self.width), random.randint(0, self.height))],fill=(random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)),width=1)# 添加噪点for _ in range(50):draw.point([random.randint(0, self.width), random.randint(0, self.height)], fill=(random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)))def _warp_image(self, image):# 创建扭曲效果width, height = image.sizenew_image = Image.new('RGB', (width, height))pixels = new_image.load()for x in range(width):for y in range(height):# 计算扭曲后的坐标new_x = int(x + (random.random() - 0.5) * 2)new_y = int(y + (random.random() - 0.5) * 2)# 确保坐标在图像范围内new_x = max(0, min(new_x, width - 1))new_y = max(0, min(new_y, height - 1))pixels[x, y] = image.getpixel((new_x, new_y))return new_image# 使用示例generator = CaptchaGenerator()image, text = generator.generate_image()image.save('captcha.png')print("验证码文本:", text)

  二、Web集成与验证

  1. Flask集成示例

  pythonfrom flask import Flask, session, make_response, request, jsonifyimport ioimport timeapp = Flask(__name__)app.secret_key = 'your_secret_key_here' # 必须设置密钥# 验证码存储字典(生产环境建议用Redis)captcha_store = {}@app.route('/captcha')def captcha():generator = CaptchaGenerator()img_io = io.BytesIO()image, text = generator.generate_image()image.save(img_io, 'PNG')img_io.seek(0)# 存储验证码(设置5分钟过期)captcha_id = str(time.time())captcha_store[captcha_id] = {'text': text,'expire': time.time() + 300 # 5分钟后过期}response = make_response(img_io.getvalue())response.headers['Content-Type'] = 'image/png']response.headers['Captcha-Id'] = captcha_id # 返回验证码IDreturn response@app.route('/verify', methods=['POST'])def verify():data = request.get_json()captcha_id = data.get('captcha_id')user_input = data.get('captcha_text', '').strip().lower()# 检查验证码是否存在且未过期captcha_data = captcha_store.get(captcha_id)if not captcha_data or time.time() > captcha_data['expire']:return jsonify({'success': False, 'message': '验证码已过期'})# 验证并删除已使用的验证码if user_input == captcha_data['text'].lower():del captcha_store[captcha_id]return jsonify({'success': True})else:return jsonify({'success': False, 'message': '验证码错误'})if __name__ == '__main__':app.run(debug=True)

python如何编写验证码程序.jpg

  三、进阶功能与安全考虑

  1. 使用专业库简化开发

  python# 使用captcha库(更简单高效)from captcha.image import ImageCaptchadef generate_with_captcha_lib():image = ImageCaptcha(width=120, height=40)captcha_text = ''.join(random.choices(string.ascii_letters + string.digits, k=4))data = image.generate(captcha_text)image.write(captcha_text, 'captcha_lib.png')return captcha_text

  2. 安全增强措施

  验证码复杂度控制:

  混合大小写字母和数字

  避免使用容易混淆的字符(如0/O, 1/l)

  字符数建议在4-6个之间

  防护措施:

  限制验证尝试次数

  验证码一次性使用,验证后立即失效

  记录失败尝试,异常时触发人机验证

  高级技术:

  行为验证:记录用户鼠标轨迹、点击位置等

  滑块验证码:要求用户拖动滑块完成拼图

  短信/邮箱验证码:作为图片验证码的补充

  3. 生产环境建议

  存储方案:

  使用Redis存储验证码,设置过期时间

  分布式环境下考虑使用共享存储

  性能优化:

  预生成验证码图片模板

  使用缓存减少重复计算

  监控与日志:

  记录验证码生成和验证日志

  监控异常验证行为

  四、完整示例(简化版)

  python# 完整验证码服务类import redisimport timeimport hashlibclass CaptchaService:def __init__(self, redis_url='redis://localhost:6379/0'):self.redis = redis.from_url(redis_url)self.generator = CaptchaGenerator()def generate(self):image, text = self.generator.generate_image()# 生成唯一IDcaptcha_id = hashlib.sha256(str(time.time()).encode()).hexdigest()[:16]# 存储到Redis,5分钟过期self.redis.setex(f"captcha:{captcha_id}", 300, text.lower())# 返回二进制图片和IDimg_bytes = io.BytesIO()image.save(img_bytes, format='PNG')return captcha_id, img_bytes.getvalue()def verify(self, captcha_id, user_input):if not captcha_id or not user_input:return False# 从Redis获取验证码stored_text = self.redis.get(f"captcha:{captcha_id}")if not stored_text:return False# 验证后删除self.redis.delete(f"captcha:{captcha_id}")return user_input.lower() == stored_text.decode().lower()

  Python实现验证码系统需要关注以下几个方面:

  验证码生成算法(字符集、干扰元素、扭曲效果)

  存储与验证机制(一次性使用、过期时间)

  安全防护措施(防暴力破解、防自动化)

  生产环境部署(分布式存储、性能优化)

  对于大多数应用,使用captcha等专业库配合Redis存储即可满足需求。高安全要求的场景可以考虑结合多种验证方式,如短信验证码+行为验证等。完整系统需结合前端展示和后端存储,并添加干扰措施提升安全性。


猜你喜欢