.net点选验证码实现思路分享

news/2024/2/21 2:44:09

哈哈好久没冒泡了,最进看见点选验证码有点意思,所以想自己写一个。

先上效果图

如果你被这个效果吸引了就请继续看下去。

贴代码前先说点思路:

1.要有一个汉字库,并按字形分类。(我在数据库里是安部首分类的)

2.获取验证码(也就是取几个文字做验证码)

3.根据取出来的文字去找形近字

4.排列验证码文字和形近字

5.绘制图片

6.显示

6.写个博客分享一下(分享代码改变世界)

一、获取字库

  我国文化博大精深,辣么多的字从哪儿来?当然我不可能手动加进去,于是我就在网上随便找了一个能查汉字的网站,去抓别人的数据。抓数据的方法请点传送门。传送门里说的只是思路,如果有不明白的请艾特我。我会在下面共享我的字库。

二、获取验证码

这个就比较简单了这里我就直接贴代码了,下面的代码就是随机排序后取4条数据,我这样写是为了图方便。个人觉得先随机生成ID,然后直接根据ID取数据,这样查询速度会比下面这种写法快。(注意我用的数据库是MySql)

      /// <summary>/// 获取验证码/// </summary>public List<VerificationCode.Model.WenZhi> GetCodeText(){const string sql = "SELECT * FROM wenzhi ORDER BY RAND() LIMIT 4";var dataReader = dbHelper.GetDataReader(sql);var list = DataReaderToList(dataReader);dataReader.Close();return list;}

 

三、根据取出来的文字去找形近字

  因为第一步的时候我存部首了,所以这里我直接根据部首取获取当前部首的形近字。

        /// <summary>/// 获取答案备选/// </summary>/// <param name="buShouCode">部首编码</param>/// <param name="id">当前文字ID</param>/// <param name="number">数量</param>/// <returns></returns>public List<VerificationCode.Model.WenZhi> GetAnswer(string buShouCode, int id,int number=){string sql = $"SELECT * FROM wenzhi where BuShouCode='{buShouCode}' and ID <> {id} ORDER BY RAND() LIMIT "+ number;var dataReader = dbHelper.GetDataReader(sql);var list = DataReaderToList(dataReader);dataReader.Close();return list;}

四.排列验证码文字和形近字

  下面的代码是先把备选答案和验证码放在一个集合里然后再对集合排序

 public Model.Code GetCode(){var wenzlist = _wenZhiDal.GetCodeText();  //获取验证码var listAnsuwr = new List<Answer>();//实例化备选答案对象var answerCode = string.Empty;//答案var result = new Model.Code{Id = Guid.NewGuid().ToString()};//根据验证码获取备选答案并把添加到答案添加到备选答案集合foreach (var item in wenzlist){answerCode += item.ID + ",";result.AnswerValue += item.Text;var answerList = _wenZhiDal.GetAnswer(item.BuShouCode, item.ID);listAnsuwr.Add(new Answer { Id = item.ID.ToString(), Img = GetImage(item.Text) });listAnsuwr.AddRange(answerList.Select(answer => new Answer { Id = answer.ID.ToString(), Img = GetImage(answer.Text) }));}//如果答案个数不够就再去取几个if (listAnsuwr.Count < ){var ran = new Random();var randKey = ran.Next(, );var item = wenzlist[randKey];var answerList = _wenZhiDal.GetAnswer(item.BuShouCode, item.ID,  - listAnsuwr.Count);listAnsuwr.AddRange(answerList.Select(answer => new Answer { Id = answer.ID.ToString(), Img = GetImage(answer.Text) }));}result.CodeImg = GetImage(result.AnswerValue);//获取图片result.AnswerValue = answerCode.TrimEnd(',');result.Answer = RandomSortList(listAnsuwr);//打乱正确答案与形近字的顺序return result;}

这是对集合排序的代码        

       /// <summary>/// 随机排列集合/// </summary>/// <typeparam name="T"></typeparam>/// <param name="listT"></param>/// <returns></returns>private static List<T> RandomSortList<T>(IEnumerable<T> listT){var random = new Random();var newList = new List<T>();foreach (var item in listT){newList.Insert(random.Next(newList.Count + ), item);}return newList;}

五、绘制图片

下面是画图的代码,验证码和备选答案对应两种不同的画法(里面注释写的还算清楚)。不要担心文字旋转x°后人类分不出来,哈哈。代码最后一句我把图片转成了Base64,方便前端调用。

private static string GetImage(string text){Image image;switch (text.Length){case :image = new Bitmap(, );break;case :image = new Bitmap(, );break;default:image = new Bitmap(, );break;}Brush brushText = new SolidBrush(Color.FromArgb(, , , ));var graphics = Graphics.FromImage(image);graphics.SmoothingMode = SmoothingMode.AntiAlias;graphics.Clear(Color.White);var font = new Font(new FontFamily("华文彩云"), , FontStyle.Regular);if (text.Length > )//画验证码{//先来两条直线做干扰 然后再画文字graphics.DrawLine(new Pen(brushText, new Random().Next(, )), new Point(new Random().Next(, ), new Random().Next(, )), new Point(new Random().Next(, ), new Random().Next(, )));graphics.DrawLine(new Pen(brushText, new Random().Next(, )), new Point(new Random().Next(, ), new Random().Next(, )), new Point(new Random().Next(, ), new Random().Next(, )));graphics.DrawString(text, font, brushText, , );}else//画备选答案{Point middle = new Point(, );graphics.TranslateTransform(middle.X, middle.Y);//这里是360°随机旋转graphics.RotateTransform(new Random().Next(, ));var format = new StringFormat(StringFormatFlags.NoClip){Alignment = StringAlignment.Center,LineAlignment = StringAlignment.Center};graphics.DrawString(text, font, brushText, , , format);}brushText.Dispose();graphics.Dispose();return ImageToBase64(image);}

六、显示

直接调用GetCode方法就能返回验证码对象

下面是后台代码,应为正确答案是放在AnswerValue里的所以我先把取出来放Session里面,然后把值清空后再通过json返回给浏览器。

    public string GetVerCode(){var code = new VerificationCode.Code().GetCode();Session["VERCODE"] = code.AnswerValue;code.AnswerValue = "";return JsonConvert.SerializeObject(code);}

现在来堆点html代码        

<div class="form-group"><ul class="vercode"><li><img src=''/></li><li><img src=''/></li><li><img src=''/></li><li><img src=''/></li><li class="delete" onclick="delete_input()"></li></ul><div><img id="code-image"/> <a href="javascript:void(0);" onclick="load_vercode()">看不清?</a></div><ul class="vercode-anwser"><li><img /></li><li><img /></li><li><img /></li><li><img /></li><li><img /></li><li><img /></li><li><img /></li><li><img /></li><li><img /></li></ul></div>

再来点js代码,这里只实现的图片上的效果,还没对数据验证(这里说说验证思路:每个图片对应一个ID,取到选择图片的ID用逗号分隔,然后与Session里的值对比)

<script>$(function () {//加载验证码load_vercode();//绑定验证码点击事件$(".vercode-anwser").find("img").on("click", null, function () {$(".vercode").find("img[src='']:eq(0)").attr("src", $(this).attr("src"));});});function load_vercode() {$(".vercode").find("img").attr("src", "");$.get("GetVerCode", function (data) {var result = JSON.parse(data);$("#code-image").attr("src", "data:image/png;base64," + result.CodeImg);$(".vercode-anwser").find("img").each(function (index) {$(this).attr("src", "data:image/png;base64," + result.Answer[index].Img);});});}//删除事件function delete_input() {$(".vercode").find("img[src!='']:last").attr("src", "");}</script>

到这里代码就差不多了,以上思路只是单纯的个人想法,有兴趣的朋友一起来讨论吧。


http://www.ppmy.cn/news/573825.html

相关文章

SSMP整合案例(6) 业务service层逻辑编写

之前呢 我们就还是将数据层的结构搭好了 那么 接下来就是业务层 可能有些开发人员会存在一定的误区 将业务层和数据层的函数命名混为一谈 例如 我们有个 users 表 那么 我们要做一个登录功能 那么 业务层的接口毋庸置疑叫 login 接收两个参数 userName userPassword 然后 数据…

hp380g10服务器安装系统,hp380G10服务器安装centos6.9和显卡驱动-Go语言中文社区

首先bios选项 保存退出&#xff0c;否则驱动安装完成后&#xff0c;系统将无法启动。显卡输出口也将无视频信息输出。 下面将nouveau加入黑名单&#xff0c;重建img文件。 echo "blacklist nouveau" >>/etc/modprobe.d/blacklist.conf mv /boot/initramfs-$(un…

Linux安装显卡驱动后闪屏问题

Linux安装显卡驱动后闪屏问题 写在前面的话&#xff1a; 作为一个linux小白&#xff0c;这几天为了实验给电脑装linux系统&#xff0c;在安装完linux显卡驱动之后&#xff0c;出现电脑&#xff08;HP&#xff09;每十几秒黑屏闪一下屏幕又瞬间黑屏的情况&#xff0c;忙了一个…

ubuntu18.04安装nvidia显卡驱动的正确方法

最近&#xff0c;我在HP 战99 AMD版的笔记本上安装ubuntu18.04系统。在网络上百度了一大堆的有关安装nvidia驱动的方法&#xff0c;后来试了五六次&#xff0c;结果都是以失败告终&#xff0c;为此ubuntu系统还重装了两三次&#xff0c;简直快到了崩溃的边缘。 也许&#xff0c…

linux加载显卡驱动模块,linux怎样加载显卡驱动,急,在线等

应该和下面的安装差不多。不过文件名不一样。 1&#xff0e; 先mount光驱 2&#xff0e; 在光盘下找到 /compaq/csp/linux目录&#xff0c;其中有个叫install700.sh的文件 3&#xff0e; 如果字符界面直接输入 ./install700.sh –y –nui 就可以选择性的安装组件了 以下是输入后…

Ubuntu20.04显卡驱动安装

我的安装并(hen)不顺利&#xff0c;所以以下内容仅供参考&#xff0c;可能不适用其他电脑。 目 录 电脑基本信息驱动安装过程&#xff1a;原因分析&#xff1a;References 电脑基本信息 OS&#xff1a;ubuntu20.04 LTS双系统&#xff08;WIN10&#xff09;。 电脑&#xff1a…

ubuntu20.04下安装nvidia显卡驱动

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、主要参考资料二、基于上述教程的修正1.显卡驱动下载2.gcc编译环境 前言 如题 一、主要参考资料 参考博客为https://www.cnblogs.com/Fight-go/p/1582835…

ubuntu18.04显卡驱动安装

原文&#xff1a;https://blog.csdn.net/qq_37935670/article/details/80377196** 弄显卡驱动弄了很久&#xff0c;主要是因为网上的解答良莠不齐且版本并不适合。套路比较深。以下我的解答可能不具有普适性&#xff0c;仅供参考&#xff01; 本人双显卡&#xff0c;intel集成显…

Go学习圣经:Go语言实现高并发CRUD业务开发

说在前面&#xff1a; 现在拿到offer超级难&#xff0c;甚至连面试电话&#xff0c;一个都搞不到。 尼恩的技术社群中&#xff08;50&#xff09;&#xff0c;很多小伙伴凭借 “左手云原生右手大数据”的绝活&#xff0c;拿到了offer&#xff0c;并且是非常优质的offer&#…

【计算机网络自顶向下】电子邮件简答题总结

电子邮件 SMTP、POP3、IMAP、HTTP SMTP 客户端使用TCP来可靠传输到服务器端口号25邮件消息必须是7-bit ASCII直接传送&#xff1a;用于发送服务器到接收服务器邮件消息的格式: 多媒体扩展&#xff1a;增添额外信头头部声明MIME 总结&#xff1a; 过程 握手邮件消息的传输结束…

分享一个可交互的小场景(一)

先看效果&#xff1a; 可互动的小场景 再看代码&#xff1a; 1、代码较长&#xff0c;分成了几部分上传&#xff0c;先看头部和CSS <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>可交互的小场景&l…

最强连连看辅助(python)

扣扣游戏大厅连连看最强辅助代码 本程序设计非常适合初学python的程序员们&#xff0c;基本原理就是用python实现鼠标自动化控制&#xff0c;通过图像相似性比较算法和连连看消除算法从而实现连连看快速消除。 部分算法和代码有所借鉴&#xff1a; https://blog.csdn.net/qq_…

Python实现QQ游戏连连看外挂秒杀

项目地址 https://github.com/GitHub-Laziji/lianliankan 简介 200 行Python 实现的qq连连看 辅助, 用于学习, 请不要拿去伤害玩家们… 使用环境 win7 win10测试了无法使用 使用方法 开始游戏后运行就行了, 再次提示, 请在练习模式中使用, 否则可能会被其他玩家举报 …

qq连连看看外挂-我的QQ连连看“辅助”程序源码

像 连连看这一类外挂其实还算是比较简单的了&#xff0c;只要找出棋盘基址&#xff0c;加上点算法&#xff0c;就算是OK的了。   对于怎么找QQ 连连看的棋盘基址呢&#xff1f;   工具只用CE&#xff08;Cheat Engine&#xff09;就足够了&#xff0c;TX没做什么保护的&a…

200行Python实现连连看辅助

200 行Python 实现的qq连连看 辅助, 用于学习, 请不要拿去伤害玩家们... 原文博客地址 https://laboo.top/2018/11/07/... 项目地址 https://github.com/GitHub-Laziji/lianliankan 使用环境 win7 win10测试了无法使用 使用方法 开始游戏后运行就行了, 再次提示, 请在练习模式中…

游戏外挂篇:如何Dump内存获得游戏的辅助

转载请标明出处&#xff1a; https://dujinyang.blog.csdn.net/article/category/9267855 本文出自:【奥特曼超人的博客】 本篇邀请了 “阿七” 做个 外挂辅助入门篇 分享&#xff0c;之前公众号也分享过了。 最近女朋友都在玩游戏&#xff0c;晚上还不理人&#xff0c;刚好近期…

用MFC开发1连连看辅助器

首先介绍下要用到的几个API函数 1、通过标题获取窗口句柄 HWND hGameFindWindow(NULL,_T("QQ游戏 - 连连看角色版")); 2、 获得游戏窗口的位置信息 RECT gameRect GetWindowRect(hGame,&gameRect); 3、改变鼠标位置坐标 SetCursorPos(x,y); 4、得到鼠标…

C语言构建连连看游戏(矩阵方式)

C语言构建连连看游戏 设计要求 用数字英文字母&#xff0c;采用文本输出的方式。每次输出一个8*10的矩形&#xff0c;然后等待玩家输入两个数字或字母的坐标&#xff0c;如果满足消除规则就输出新的矩形。 注意&#xff1a;考虑类似迷宫的处理方式&#xff0c;在8 * 10矩形之…

c语言中文网qq,c语言写的qq连看辅助

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 #include #include int click(HWND, int, int); int isclick(HWND, int, int); int main() { HWND hwnd; DWORD pid0, bt0; HANDLE hProcess; DWORD base_address 0x00129FB4; char map[210]; int x, y, x1, y1, i, j; char *z…

VC++制作连连看辅助经验分享

最近看了郁金香老师的《VC外挂编程》系列视频&#xff0c;试着按这个思路写了一个笔者自己的连连看外挂。试验了一下&#xff0c;比较成功&#xff0c;已经从0分刷到了近20000分。下面来分享一下经验。 首先说明一下需要用到的工具&#xff1a; 1、 CE(cheat engine)&#xf…
最新文章