溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

如何使用asp.net實(shí)現(xiàn)點(diǎn)選驗(yàn)證碼

發(fā)布時(shí)間:2021-09-13 17:37:06 來源:億速云 閱讀:120 作者:小新 欄目:編程語言

這篇文章將為大家詳細(xì)講解有關(guān)如何使用asp.net實(shí)現(xiàn)點(diǎn)選驗(yàn)證碼,小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。

先上效果圖

如何使用asp.net實(shí)現(xiàn)點(diǎn)選驗(yàn)證碼

如果你被這個(gè)效果吸引了就請(qǐng)繼續(xù)看下去。

貼代碼前先說點(diǎn)思路:

1.要有一個(gè)漢字庫,并按字形分類。(我在數(shù)據(jù)庫里是安部首分類的)

2.獲取驗(yàn)證碼(也就是取幾個(gè)文字做驗(yàn)證碼)

3.根據(jù)取出來的文字去找形近字

4.排列驗(yàn)證碼文字和形近字

5.繪制圖片

6.顯示

一、獲取字庫

我國文化博大精深,辣么多的字從哪兒來?當(dāng)然我不可能手動(dòng)加進(jìn)去,于是我就在網(wǎng)上隨便找了一個(gè)能查漢字的網(wǎng)站,去抓別人的數(shù)據(jù)。抓數(shù)據(jù)的方法請(qǐng)點(diǎn)傳送門。傳送門里說的只是思路,如果有不明白的請(qǐng)艾特我。我會(huì)在下面共享我的字庫。

二、獲取驗(yàn)證碼

這個(gè)就比較簡單了這里我就直接貼代碼了,下面的代碼就是隨機(jī)排序后取4條數(shù)據(jù),我這樣寫是為了圖方便。個(gè)人覺得先隨機(jī)生成ID,然后直接根據(jù)ID取數(shù)據(jù),這樣查詢速度會(huì)比下面這種寫法快。(注意我用的數(shù)據(jù)庫是MySql

  /// <summary>
  /// 獲取驗(yàn)證碼
  /// </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;
  }

三、根據(jù)取出來的文字去找形近字

因?yàn)榈谝徊降臅r(shí)候我存部首了,所以這里我直接根據(jù)部首取獲取當(dāng)前部首的形近字。

  /// <summary>
  /// 獲取答案備選
  /// </summary>
  /// <param name="buShouCode">部首編碼</param>
  /// <param name="id">當(dāng)前文字ID</param>
  /// <param name="number">數(shù)量</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(sql);
   var list = DataReaderToList(dataReader);
   dataReader.Close();
   return list;
  }

四.排列驗(yàn)證碼文字和形近字

下面的代碼是先把備選答案和驗(yàn)證碼放在一個(gè)集合里然后再對(duì)集合排序

 public Model.Code GetCode()
  {
   
   var wenzlist = _wenZhiDal.GetCodeText(); //獲取驗(yàn)證碼
   var listAnsuwr = new List<Answer>();//實(shí)例化備選答案對(duì)象
   var answerCode = string.Empty;//答案
   var result = new Model.Code
   {
    Id = Guid.NewGuid().ToString()
   };
   //根據(jù)驗(yàn)證碼獲取備選答案并把添加到答案添加到備選答案集合
   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) }));
   }
   //如果答案個(gè)數(shù)不夠就再去取幾個(gè)
   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;
  }

這是對(duì)集合排序的代碼

  /// <summary>
  /// 隨機(jī)排列集合
  /// </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;
  }

五、繪制圖片

下面是畫圖的代碼,驗(yàn)證碼和備選答案對(duì)應(yīng)兩種不同的畫法(里面注釋寫的還算清楚)。不要擔(dān)心文字旋轉(zhuǎn)x°后人類分不出來,哈哈。代碼最后一句我把圖片轉(zhuǎn)成了Base64,方便前端調(diào)用。

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)//畫驗(yàn)證碼
   {
    //先來兩條直線做干擾 然后再畫文字
    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°隨機(jī)旋轉(zhuǎn) 
    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);
  }

六、顯示

直接調(diào)用GetCode方法就能返回驗(yàn)證碼對(duì)象

下面是后臺(tái)代碼,應(yīng)為正確答案是放在AnswerValue里的所以我先把取出來放Session里面,然后把值清空后再通過json返回給瀏覽器。

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

現(xiàn)在來堆點(diǎn)html代碼

<p 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>
     <p>
      <img id="code-image"/> <a href="javascript:void(0);" onclick="load_vercode()">看不清?</a>
     </p>
     <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>
    </p>

再來點(diǎn)js代碼,這里只實(shí)現(xiàn)的圖片上的效果,還沒對(duì)數(shù)據(jù)驗(yàn)證(這里說說驗(yàn)證思路:每個(gè)圖片對(duì)應(yīng)一個(gè)ID,取到選擇圖片的ID用逗號(hào)分隔,然后與Session里的值對(duì)比)

<script>
  $(function () {
   //加載驗(yàn)證碼
   load_vercode();
   //綁定驗(yàn)證碼點(diǎn)擊事件
   $(".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>

關(guān)于“如何使用asp.net實(shí)現(xiàn)點(diǎn)選驗(yàn)證碼”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,使各位可以學(xué)到更多知識(shí),如果覺得文章不錯(cuò),請(qǐng)把它分享出去讓更多的人看到。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI