• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

.net点选验证码实现思路

武飞扬头像
lmr廖
帮助1

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

先上效果图

学新通

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

贴代码前先说点思路:

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

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

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

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

5.绘制图片

6.显示

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

一、获取字库

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

二、获取验证码

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

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

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

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

  1.  
    /// <summary>
  2.  
    /// 获取答案备选
  3.  
    /// </summary>
  4.  
    /// <param name="buShouCode">部首编码</param>
  5.  
    /// <param name="id">当前文字ID</param>
  6.  
    /// <param name="number">数量</param>
  7.  
    /// <returns></returns>
  8.  
    public List<VerificationCode.Model.WenZhi> GetAnswer(string buShouCode, int id,int number=)
  9.  
    {
  10.  
    string sql = $"SELECT * FROM wenzhi where BuShouCode='{buShouCode}' and ID <> {id} ORDER BY RAND() LIMIT " number;
  11.  
    var dataReader = dbHelper.GetDataReader(sql);
  12.  
    var list = DataReaderToList(dataReader);
  13.  
    dataReader.Close();
  14.  
    return list;
  15.  
    }
学新通

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

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

  1.  
    public Model.Code GetCode()
  2.  
    {
  3.  
     
  4.  
    var wenzlist = _wenZhiDal.GetCodeText(); //获取验证码
  5.  
    var listAnsuwr = new List<Answer>();//实例化备选答案对象
  6.  
    var answerCode = string.Empty;//答案
  7.  
    var result = new Model.Code
  8.  
    {
  9.  
    Id = Guid.NewGuid().ToString()
  10.  
    };
  11.  
    //根据验证码获取备选答案并把添加到答案添加到备选答案集合
  12.  
    foreach (var item in wenzlist)
  13.  
    {
  14.  
    answerCode = item.ID ",";
  15.  
    result.AnswerValue = item.Text;
  16.  
    var answerList = _wenZhiDal.GetAnswer(item.BuShouCode, item.ID);
  17.  
    listAnsuwr.Add(new Answer { Id = item.ID.ToString(), Img = GetImage(item.Text) });
  18.  
    listAnsuwr.AddRange(answerList.Select(answer => new Answer { Id = answer.ID.ToString(), Img = GetImage(answer.Text) }));
  19.  
    }
  20.  
    //如果答案个数不够就再去取几个
  21.  
    if (listAnsuwr.Count < )
  22.  
    {
  23.  
    var ran = new Random();
  24.  
    var randKey = ran.Next(, );
  25.  
    var item = wenzlist[randKey];
  26.  
    var answerList = _wenZhiDal.GetAnswer(item.BuShouCode, item.ID, - listAnsuwr.Count);
  27.  
    listAnsuwr.AddRange(answerList.Select(answer => new Answer { Id = answer.ID.ToString(), Img = GetImage(answer.Text) }));
  28.  
    }
  29.  
    result.CodeImg = GetImage(result.AnswerValue);//获取图片
  30.  
    result.AnswerValue = answerCode.TrimEnd(',');
  31.  
    result.Answer = RandomSortList(listAnsuwr);//打乱正确答案与形近字的顺序
  32.  
    return result;
  33.  
    }
学新通

这是对集合排序的代码        

  1.  
    /// <summary>
  2.  
    /// 随机排列集合
  3.  
    /// </summary>
  4.  
    /// <typeparam name="T"></typeparam>
  5.  
    /// <param name="listT"></param>
  6.  
    /// <returns></returns>
  7.  
    private static List<T> RandomSortList<T>(IEnumerable<T> listT)
  8.  
    {
  9.  
    var random = new Random();
  10.  
    var newList = new List<T>();
  11.  
    foreach (var item in listT)
  12.  
    {
  13.  
    newList.Insert(random.Next(newList.Count ), item);
  14.  
    }
  15.  
    return newList;
  16.  
    }
学新通

五、绘制图片

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

  1.  
    private static string GetImage(string text)
  2.  
    {
  3.  
    Image image;
  4.  
    switch (text.Length)
  5.  
    {
  6.  
    case :
  7.  
    image = new Bitmap(, );
  8.  
    break;
  9.  
    case :
  10.  
    image = new Bitmap(, );
  11.  
    break;
  12.  
    default:
  13.  
    image = new Bitmap(, );
  14.  
    break;
  15.  
    }
  16.  
    Brush brushText = new SolidBrush(Color.FromArgb(, , , ));
  17.  
    var graphics = Graphics.FromImage(image);
  18.  
    graphics.SmoothingMode = SmoothingMode.AntiAlias;
  19.  
    graphics.Clear(Color.White);
  20.  
    var font = new Font(new FontFamily("华文彩云"), , FontStyle.Regular);
  21.  
    if (text.Length > )//画验证码
  22.  
    {
  23.  
    //先来两条直线做干扰 然后再画文字
  24.  
    graphics.DrawLine(new Pen(brushText, new Random().Next(, )), new Point(new Random().Next(, ), new Random().Next(, )), new Point(new Random().Next(, ), new Random().Next(, )));
  25.  
    graphics.DrawLine(new Pen(brushText, new Random().Next(, )), new Point(new Random().Next(, ), new Random().Next(, )), new Point(new Random().Next(, ), new Random().Next(, )));
  26.  
    graphics.DrawString(text, font, brushText, , );
  27.  
     
  28.  
    }
  29.  
    else//画备选答案
  30.  
    {
  31.  
    Point middle = new Point(, );
  32.  
    graphics.TranslateTransform(middle.X, middle.Y);
  33.  
    //这里是360°随机旋转
  34.  
    graphics.RotateTransform(new Random().Next(, ));
  35.  
    var format = new StringFormat(StringFormatFlags.NoClip)
  36.  
    {
  37.  
    Alignment = StringAlignment.Center,
  38.  
    LineAlignment = StringAlignment.Center
  39.  
    };
  40.  
    graphics.DrawString(text, font, brushText, , , format);
  41.  
     
  42.  
    }
  43.  
    brushText.Dispose();
  44.  
    graphics.Dispose();
  45.  
    return ImageToBase64(image);
  46.  
    }
学新通

六、显示

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

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

  1.  
    public string GetVerCode()
  2.  
    {
  3.  
    var code = new VerificationCode.Code().GetCode();
  4.  
    Session["VERCODE"] = code.AnswerValue;
  5.  
    code.AnswerValue = "";
  6.  
    return JsonConvert.SerializeObject(code);
  7.  
    }

现在来堆点html代码        

  1.  
    <div class="form-group">
  2.  
    <ul class="vercode">
  3.  
    <li><img src=''/></li>
  4.  
    <li><img src=''/></li>
  5.  
    <li><img src=''/></li>
  6.  
    <li><img src=''/></li>
  7.  
    <li class="delete" onclick="delete_input()"></li>
  8.  
    </ul>
  9.  
    <div>
  10.  
    <img id="code-image"/> <a href="javascript:void(0);" onclick="load_vercode()">看不清?</a>
  11.  
    </div>
  12.  
    <ul class="vercode-anwser">
  13.  
    <li><img /></li>
  14.  
    <li><img /></li>
  15.  
    <li><img /></li>
  16.  
    <li><img /></li>
  17.  
    <li><img /></li>
  18.  
    <li><img /></li>
  19.  
    <li><img /></li>
  20.  
    <li><img /></li>
  21.  
    <li><img /></li>
  22.  
    </ul>
  23.  
    </div>
学新通

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

  1.  
    <script>
  2.  
    $(function () {
  3.  
    //加载验证码
  4.  
    load_vercode();
  5.  
    //绑定验证码点击事件
  6.  
    $(".vercode-anwser").find("img").on("click", null, function () {
  7.  
    $(".vercode").find("img[src='https://blog.csdn.net/lmrylll/article/details/131379578']:eq(0)").attr("src", $(this).attr("src"));
  8.  
    });
  9.  
    });
  10.  
     
  11.  
    function load_vercode() {
  12.  
    $(".vercode").find("img").attr("src", "");
  13.  
    $.get("GetVerCode", function (data) {
  14.  
    var result = JSON.parse(data);
  15.  
    $("#code-image").attr("src", "data:image/png;base64," result.CodeImg);
  16.  
    $(".vercode-anwser").find("img").each(function (index) {
  17.  
    $(this).attr("src", "data:image/png;base64," result.Answer[index].Img);
  18.  
    });
  19.  
    });
  20.  
    }
  21.  
    //删除事件
  22.  
    function delete_input() {
  23.  
    $(".vercode").find("img[src!='']:last").attr("src", "");
  24.  
    }
  25.  
    </script>
学新通

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

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhggbige
系列文章
更多 icon
同类精品
更多 icon
继续加载