后端开发|C#.Net教程
验证码
后端开发-C#.Net教程
哈哈好久没冒泡了,最进看见点选验证码有点意思,所以想自己写一个。
虚拟主机搭建网站源码,ubuntu无法识别声卡,项目导入tomcat的部署,珍宝堂爬虫,网站导航php源码,四川运营抖音seo优化优势lzw
先上效果图
shopxx 4.0正式版源码,vscode 编辑冲突,ubuntu查看磁盘读写,tomcat 标题,sqlite延时注入,arteditor保存图片到服务器,jquery产品展示插件,fh admin前端框架,python爬虫炒股,php主要用来开发什么,seo优化技术学习,歌曲网站模板,生日快乐网页,wordpress模板错位,php登陆后跳转页面,easyui权限管理系统,一个简单的java程序lzw
tcp调试工具 源码,vscode 冒号,ubuntu 开机分辨率,tomcat替换项目配置文件,sqlite声明函数,网页设计专业的工作室,韩国低价高配服务器,第三方插件中心,前端开发框架热度,爬虫读后感,新乡php,博乐seo,网站倒计时源码,预览窗口网页模板,phpcms v9手机模板,wifi认证页面模板制作,商务策划管理系统,医疗app开源程序lzw
如果你被这个效果吸引了就请继续看下去。
贴代码前先说点思路:
1.要有一个汉字库,并按字形分类。(我在数据库里是安部首分类的)
2.获取验证码(也就是取几个文字做验证码)
3.根据取出来的文字去找形近字
4.排列验证码文字和形近字
5.绘制图片
6.显示
A、获取字库
我国文化博大精深,辣么多的字从哪儿来?当然我不可能手动加进去,于是我就在网上随便找了一个能查汉字的网站,去抓别人的数据。抓数据的方法请点传送门。传送门里说的只是思路,如果有不明白的请艾特我。我会在下面共享我的字库。
B、获取验证码
这个就比较简单了这里我就直接贴代码了,下面的代码就是随机排序后取4条数据,我这样写是为了图方便。个人觉得先随机生成ID,然后直接根据ID取数据,这样查询速度会比下面这种写法快。(注意我用的数据库是MySql)
/// public List 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;}
C、根据取出来的文字去找形近字
因为第一步的时候我存部首了,所以这里我直接根据部首取获取当前部首的形近字。
/// /// 部首编码/// 当前文字ID/// 数量/// public List GetAnswer(string buShouCode, int id,int number=1){ 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();//实例化备选答案对象 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 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; }
这是对集合排序的代码
/// /// /// /// private static List RandomSortList(IEnumerable listT){ var random = new Random(); var newList = new List(); foreach (var item in listT) { newList.Insert(random.Next(newList.Count + 1), item); } return newList;}
E、绘制图片
下面是画图的代码,验证码和备选答案对应两种不同的画法(里面注释写的还算清楚)。不要担心文字旋转x°后人类分不出来,哈哈。代码最后一句我把图片转成了Base64,方便前端调用。
private static string GetImage(string text) { Image image; switch (text.Length) { case 1:image = new Bitmap(50, 40);break; case 4:image = new Bitmap(120, 40);break; default:image = new Bitmap(50, 40);break; } Brush brushText = new SolidBrush(Color.FromArgb(255, 0, 0, 0)); var graphics = Graphics.FromImage(image); graphics.SmoothingMode = SmoothingMode.AntiAlias; graphics.Clear(Color.White); var font = new Font(new FontFamily("华文彩云"), 20, FontStyle.Regular); if (text.Length > 1)//画验证码 { //先来两条直线做干扰 然后再画文字 graphics.DrawLine(new Pen(brushText, new Random().Next(1, 3)), new Point(new Random().Next(0, 10), new Random().Next(10, 40)), new Point(new Random().Next(100, 120), new Random().Next(10, 30))); graphics.DrawLine(new Pen(brushText, new Random().Next(1, 3)), new Point(new Random().Next(20, 50), new Random().Next(0, 10)), new Point(new Random().Next(100, 120), new Random().Next(30, 40))); graphics.DrawString(text, font, brushText, 0, 10); } else//画备选答案 { Point middle = new Point(25, 20); graphics.TranslateTransform(middle.X, middle.Y); //这里是360°随机旋转graphics.RotateTransform(new Random().Next(0, 360)); var format = new StringFormat(StringFormatFlags.NoClip) {Alignment = StringAlignment.Center,LineAlignment = StringAlignment.Center }; graphics.DrawString(text, font, brushText, 0, 0, format); } brushText.Dispose(); graphics.Dispose(); return ImageToBase64(image); }
F、显示
直接调用GetCode方法就能返回验证码对象
下面是后台代码,应为正确答案是放在AnswerValue里的所以我先把取出来放Session里面,然后把值清空后再通过json返回给浏览器。
public string GetVerCode(){ var code = new VerificationCode.Code().GetCode(); Session["VERCODE"] = code.AnswerValue; code.AnswerValue = ""; return JsonConvert.SerializeObject(code);}
现在来堆点html代码
看不清?
再来点js代码,这里只实现的图片上的效果,还没对数据验证(这里说说验证思路:每个图片对应一个ID,取到选择图片的ID用逗号分隔,然后与Session里的值对比)
$(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", ""); }
到这里代码就差不多了,以上思路只是单纯的个人想法,有兴趣的朋友一起来讨论吧。
更多点选验证码实现思路相关文章请关注PHP中文网!