生成随机图片验证码

news2024/11/25 14:34:25

随着互联网的不断发展,安全性问题日益突出。为了保障用户账号的安全性,很多网站都引入了验证码机制。验证码是一种区分用户是计算机还是人的公共全自动程序,可以有效防止恶意攻击和自动化脚本的滥用。本文将介绍如何使用Python生成随机图片验证码,提高网站的安全性。

效果图

在这里插入图片描述

一、准备工作

在生成随机图片验证码之前,我们需要准备一些必要的库和工具。首先,我们需要安装Python环境,然后使用pip安装以下库:

  1. PIL(Python Imaging Library):用于图像处理和操作。
  2. random:用于生成随机数。
  3. 下载字体文件:字体文件

可以通过以下命令安装这些库:

pip install pillow

二 功能介绍

1. 生成随机验证码

import random  
import string  
  
# 生成指定长度的随机验证码
all_chars = string.ascii_letters + string.digits  # 包含大小写字母和数字  
random_code = ''.join(random.choice(all_chars) for _ in range(4))  
print(random_code)

通过string生成随机大小字母数组长度为4的字符串

2. 创建图片

from PIL import Image
img = Image.new(mode='RGB', size=(120, 30), color=(255, 255, 255))
 
with open('code.png','wb') as f:
    img.save(f,format='png')

在这里插入图片描述

通过pillow模块可以创建图片, 如图可以指定图片的大小和颜色。

3. 创建画笔

from PIL import Image, ImageDraw

# 创建一个新的白色图像,大小为200x200像素  
image = Image.new('RGB', (200, 200), color=(255, 255, 255))

# 创建一个可以在给定图像上绘图的对象  
draw = ImageDraw.Draw(image)

# 画线  
# 参数分别为:起始点的x坐标,起始点的y坐标,结束点的x坐标,结束点的y坐标,线条颜色,线条宽度  
draw.line((0, 0, 200, 200), fill=(0, 0, 0), width=5)  # 从(0, 0)到(200, 200)画一条黑色线条,宽度为5  

# 画点  
# 参数分别为:点的x坐标,点的y坐标,点的颜色  
draw.point((100, 100), fill=(255, 0, 0))  # 在(100, 100)处画一个红色点  

# 画圆  
# 参数分别为:圆心的x坐标,圆心的y坐标,半径,填充颜色(可选),线条颜色(可选),线条宽度(可选)  
draw.ellipse((50, 50, 150, 150), fill=(0, 255, 0), outline=(0, 0, 255))  # 画一个绿色的圆,边缘为红色,位置由矩形的左上角和右下角坐标定义  

# 画矩形  
# 参数分别为:矩形左上角的x坐标,矩形左上角的y坐标,矩形右下角的x坐标,矩形右下角的y坐标,填充颜色(可选),线条颜色(可选),线条宽度(可选)  
draw.rectangle((10, 10, 190, 190), fill=None, outline=(0, 0, 255), width=3)  # 画一个红色的矩形框,位置由左上角和右下角坐标定义  

draw.text([100,100],'python',"red")
# 显示图像  
image.show()

在这里插入图片描述

创建画笔之后,就能在上一个步骤中创建的图片中根据自己的需要将生成的验证码画在图片上

4. 添加文字资源

font = ImageFont.truetype("kumo.ttf", 28)

使用pillow中的默认字体是正常的字体,但是这种字体容易被爬虫给破解,需要更换字体

5. 添加干扰

# 写干扰点
for i in range(20):
    draw.point([random.randint(0, self.width), random.randint(0, self.height)], fill=self.random_color())

# 写干扰圆圈
for i in range(20):
    draw.point([random.randint(0, self.width), random.randint(0, self.height)], fill=self.random_color())
    x = random.randint(0, self.width)
    y = random.randint(0, self.height)
    draw.arc((x, y, x + 4, y + 4), 0, 90, fill=self.random_color())

# 画干扰线
for i 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=self.random_color())
# 应用模糊滤镜,增加干扰效果
self.img = self.img.filter(ImageFilter.EDGE_ENHANCE_MORE)

更换了字体后安全性也不是很高,需要在图片上增加一些干扰的元素,防止爬虫失败到图片中的验证码。

未增加干扰和增加干扰的对比

在这里插入图片描述

三、使用示例

现在我们可以将上述函数结合起来,生成一个随机图片验证码,并将其保存为文件或直接在网页上显示。

import random
import string
from PIL import Image, ImageDraw, ImageFilter, ImageFont


class ImageCode:
    def __init__(self, width=120, height=30, char_length=5, font_file='kumo.ttf', font_size=28):
        self.width = width
        self.height = height
        self.char_code = None
        self.char_length = char_length
        self.font_file = font_file
        self.font_size = font_size
        self.img = Image.new(mode='RGB', size=(self.width, self.height), color=(255, 255, 255))

    def random_code(self):
        """生成指定长度的随机验证码"""
        all_chars = string.ascii_letters + string.digits  # 包含大小写字母和数字
        random_code = ''.join(random.choice(all_chars) for _ in range(self.char_length))
        return random_code

    @staticmethod
    def random_color():
        """生成随机颜色"""
        return (random.randint(0, 255), random.randint(10, 255), random.randint(64, 255))

    def draw_code(self, draw):
        """画随机码"""
        font = ImageFont.truetype(self.font_file, self.font_size)
        for i in range(self.char_length):
            char = self.char_code[i]
            h = random.randint(0, 4)
            draw.text([i * self.width / self.char_length, h], char, font=font, fill=self.random_color())

    def add_interfere(self, draw):
        """添加干扰"""
        # 写干扰点
        for i in range(20):
            draw.point([random.randint(0, self.width), random.randint(0, self.height)], fill=self.random_color())

        # 写干扰圆圈
        for i in range(20):
            draw.point([random.randint(0, self.width), random.randint(0, self.height)], fill=self.random_color())
            x = random.randint(0, self.width)
            y = random.randint(0, self.height)
            draw.arc((x, y, x + 4, y + 4), 0, 90, fill=self.random_color())

        # 画干扰线
        for i 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=self.random_color())
        # 应用模糊滤镜,增加干扰效果
        self.img = self.img.filter(ImageFilter.EDGE_ENHANCE_MORE)

    def save_image(self, image_file):
        f = open(image_file, "wb")
        self.img.save(f, format="png")

    def get_image_code(self):
        self.char_code = self.random_code()
        draw = ImageDraw.Draw(self.img, mode='RGB')
        self.draw_code(draw)
        self.add_interfere(draw)
        image_file = "image_code.png"
        self.save_image(image_file)
        return image_file, self.char_code


if __name__ == '__main__':
    img_code = ImageCode()
    image_file, image_code = img_code.get_image_code()
    print(image_file, image_code)

在这里插入图片描述
在这里插入图片描述
运行上述代码后,将生成一个名为image_code.png的图片文件,其中包含了随机生成的验证码。你可以将此图片嵌入到你的网站中,要求用户输入验证码以进行验证。

四、总结

本文介绍了如何使用Python生成随机图片验证码的过程。通过生成随机字符串和绘制干扰线,我们可以创建一个安全可靠的验证码系统,提高网站的安全性。你可以根据自己的需求进行进一步的扩展和优化,例如添加更多的干扰元素、调整字体和颜色等。希望本文对你有所帮助!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1582897.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

liunx环境变量学习总结

环境变量 在操作系统中,环境变量是一种特殊的变量,它们为运行的进程提供全局配置信息和系统环境设定。本文将介绍如何自定义、删除环境变量,特别是对重要环境变量PATH的管理和定制,以及与环境变量相关的函数使用。 自定义环境变…

多模态小记:CLIP、BLIP与BLIP2

CLIP 使用网络上爬取得到的大量图文对进行对比学习,图文匹配的是正样本,图文不匹配的是负样本,使匹配样本的embedding之间的距离尽可能小,不匹配样本间的距离尽可能大。 缺点:网上爬的数据质量差,不能进行…

个人求职简历(精选8篇)

HR浏览一份简历也就25秒左右,如果你连「好简历」都没有,怎么能找到好工作呢? 如果你不懂得如何在简历上展示自己,或者觉得怎么改简历都不出彩,那请你一定仔细读完。 互联网运营个人简历范文> 男 22 本科 AI简历…

最新! Gemini 1.5 Pro: 现已在 180 多个国家/地区发布;提供本地音频理解、系统说明、JSON 模式等功能!

概述 不久前,Gemini团队在Google AI Studio中推出了先进的Gemini 1.5 Pro模型,邀请开发者们进行体验和测试。社区成员利用Gemini模型的100万个上下文窗口进行的调试、创新和学习成果,令我们感到惊喜不已。 4月9号,Gemini团队骄傲…

C语言:指针详解(2)

目录 一、数组名的理解 二、使用指针访问数组 三、一维数组传参的本质 四、冒泡排序 五、二级指针 六、指针数组 正文开始 一、数组名的理解 在上一篇博客中我们在使用指针访问数组的内容时有这样的代码: int arr[10] {1,2,3,4,5,6,7,8,9,10}; int *p &…

基于ollama和CPU运行本地gguf量化模型

前言 本文先以Windows电脑运行为例,Linux同理 本案运行配置: Win11/CPU i5/RAM 32G (实际运行使用约占用10G) 假设你已经下载好了需要的xxx.gguf模型文件,本案: wizardcoder-python-13b-v1.0.Q5_K_M.gguf…

【Ubuntu】远程连接乌班图的方式-命令行界面、图形界面

​​​​​​系统环境:ubuntu-22.04.2-amd64.iso 连接工具:MobaXterm、windows自带远程桌面mstsc.exe 重置root密码:Ubuntu默认root密码是随机的,需要使用命令sudo passwd 进行重置。 一、命令行界面-SSH连接 1.1 SSH服务安装 …

实现多文件合并和去重的MapReduce作业

实现多文件合并和去重的MapReduce作业 问题描述 我们有多个文本文件,每个文件包含一些文本行。我们的目标是将这些文件合并成一个文件,并去除重复的行,最终得到一个去重后的文本文件。 输入文件A数据如下: 输入文件B数据如下&…

完全可定制的富文本编辑器:逻辑清晰,插件赋能 | 开源日报 No.218

ianstormtaylor/slate Stars: 28.8k License: MIT slate 是一个完全可定制的框架,用于构建富文本编辑器。 可以构建类似 Medium、Dropbox Paper 或 Google Docs 的富文本编辑器通过一系列插件实现所有逻辑,避免代码复杂度受到 Draft.js、Prosemirror 和…

行锁升级表锁如何避免?表锁后如何排查?

一、那些场景会造成行锁升级表锁 说明: InnoDB引擎3种行锁算法(Record Lock、Gap Lock、Next-key Lock)都是锁定的索引。 当触发X锁(写锁)的where条件 无索引 或 索引失效 时,查询的方式就变成全表扫描&…

【机器学习】科学库使用第4篇:Matplotlib,学习目标【附代码文档】

机器学习(科学计算库)完整教程(附代码资料)主要内容讲述:机器学习(常用科学计算库的使用)基础定位、目标,机器学习概述定位,目标,学习目标,学习目标,1 人工智能应用场景,2 人工智能小…

AI实时换天解决方案:重塑汽车与旅行拍摄新视界

在汽车拍摄与旅行摄影领域,天空作为画面中的重要元素,往往决定着整体视觉效果的成败。美摄科技作为业界领先的AI视觉技术提供商,近日推出了全新的AI实时换天解决方案,为用户带来了前所未有的创意空间与效率提升。 传统的换天技术…

【简单讲解下WebView的使用与后退键处理】

🌈个人主页: 程序员不想敲代码啊 🏆CSDN优质创作者,CSDN实力新星,CSDN博客专家 👍点赞⭐评论⭐收藏 🤝希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共…

分布式文件系统——MinIo

1. 文件系统和分布式文件系统 1.1 文件系统 文件系统是负责管理和存储文件的系统软件,操作系统通过文件系统提供的接口去存取文件,用户通过操作系统访问磁盘上的文件。 1.2 分布式文件系统 一个计算机无法存储海量的文件,通过网络将若干计算…

Xshell连接CentOS7教程

一、在CentOS7中单击右键,打开命令行终端: 二、输入ifconfig命令之后,找到CentOS的ip地址: 三、打开Xshell,命令行中输入 “ssh 用户名上述查到的ip地址 ”,之后输入密码即可连接成功: 四、测试…

【鸿蒙开发】组件状态管理@Prop,@Link,@Provide,@Consume,@Observed,@ObjectLink

1. Prop 父子单向同步 概述 Prop装饰的变量和父组件建立单向的同步关系: Prop变量允许在本地修改,但修改后的变化不会同步回父组件。当父组件中的数据源更改时,与之相关的Prop装饰的变量都会自动更新。如果子组件已经在本地修改了Prop装饰…

嵌入式开发绝招:状态机+事件驱动框架

生活中有很多事件驱动的例子,上自习瞒着老师偷睡觉就是很生动的一个。在开始前我有一些资料,是我根据网友给的问题精心整理了一份「嵌入式的资料从专业入门到高级教程」, 点个关注在评论区回复“888”之后私信回复“888”,全部无…

第十四届蓝桥杯C/C++大学B组题解(二)

6、岛屿个数 #include <bits/stdc.h> using namespace std; const int M51; int T,m,n; int vis[M][M],used[M][M]; int dx[]{1,-1,0,0,1,1,-1,-1}; int dy[]{0,0,1,-1,1,-1,1,-1}; string mp[M]; struct node{//记录一点坐标 int x,y; }; void bfs_col(int x,int y){ qu…

基于BP神经网络的时间序列预测模型matlab代码

整理了基于BP神经网络的时间序列预测模型matlab代码&#xff0c;包含数据集。采用了四个评价指标R2、MAE、MBE、MAPE对模型的进行评价。BP模型在数据集上表现优异。 代码获取链接&#xff1a;基于BP神经网络的时间序列预测模型matlab代码 训练效果&#xff1a; 训练集数据的R…

(学习日记)2024.04.11:UCOSIII第三十九节:软件定时器

写在前面&#xff1a; 由于时间的不足与学习的碎片化&#xff0c;写博客变得有些奢侈。 但是对于记录学习&#xff08;忘了以后能快速复习&#xff09;的渴望一天天变得强烈。 既然如此 不如以天为单位&#xff0c;以时间为顺序&#xff0c;仅仅将博客当做一个知识学习的目录&a…