来自  资质荣誉 2019-09-23 19:29 的文章
当前位置: 澳门太阳娱乐手机登录 > 资质荣誉 > 正文

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

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

先上效果图

图片 1

举个例子你被那几个职能吸引了就请继续看下来。

贴代码前先说点思路:

1.要有贰个汉字库,并按字形分类。(小编在数据Curry是安部首分拣的)

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;            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=1)        {            string sql = $"SELECT * FROM wenzhi where BuShouCode='{buShouCode}' and ID <> {id} ORDER BY RAND() LIMIT "+ number;            var dataReader = dbHelper.GetDataReader;            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 < 9)            {                var ran = new Random();                var randKey = ran.Next(0, 4);                var item = wenzlist[randKey];                var answerList = _wenZhiDal.GetAnswer(item.BuShouCode, item.ID, 9 - 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 + 1), item);            }            return newList;        }

五、绘制图片

下边是画画的代码,验证码和筹划答案对应二种不一样的画法(里面注释写的还算清楚)。不要操心文字旋转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;            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;        }

六、显示

平昔调用GetCode方法就能够再次回到验证码对象

上面是后台代码,应该为正确答案是放在AnswerValue里的所以作者先把抽出来放Session里面,然后把值清空后再通过json再次来到给浏览器。

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

于今来堆点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;" 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.on("click", null, function () {                $(".vercode").find("img[src='']:eq.attr("src", $(this).attr("src"));            });        });        function load_vercode() {            $(".vercode").find.attr("src", "");            $.get("GetVerCode", function  {                var result = JSON.parse;                $("#code-image").attr("src", "data:image/png;base64," + result.CodeImg);                $(".vercode-anwser").find.each(function  {                    $(this).attr("src", "data:image/png;base64," + result.Answer[index].Img);                });            });        }        //删除事件        function delete_input() {            $(".vercode").find("img[src!='']:last").attr("src", "");        }    </script>

到此处代码就差不离了,以上思路只是独自的民用主见,有意思味的心上人一块来谈谈吗。

源代码在这里-->地址 密码:7iud

享受代码改造世界

本文由澳门太阳娱乐手机登录发布于 资质荣誉,转载请注明出处:net点选验证码实现思路分享

关键词: