首頁 後端開發 C#.Net教程 實作一個驗證碼產生類別(含數字,拼音,漢字)

實作一個驗證碼產生類別(含數字,拼音,漢字)

Jul 03, 2017 pm 05:25 PM
數位 產生 驗證

本文和大家分享的是一個整合1:小寫拼音;2:大寫拼音;3:數字;4:漢字的驗證碼生成類別。本章範例也會有一個mvc使用驗證碼校驗的場景。具有一定的參考價值,下面跟著小編一起來看下吧

本次和大家分享的是一個集成1:小寫拼音2:大寫拼音3:數字4:漢字的驗證碼生成類,從標題來看感覺很普通的樣子,沒錯的確很普通,只是這個驗證碼類生成的時候可以透過參數指定驗證碼返回格式的規則,更主要的是希望能給大家帶來一定的實用性,本章例子也會有一個mvc使用驗證碼校驗的場景,希望大家能夠喜歡。

» 驗證碼產生流程圖

» 驗證碼產生池程式碼的解析

» 把驗證程式碼畫到圖片上

» mvc登入操作測試驗證碼正確性

下面一步一腳印的來分享:

» 驗證碼產生流程圖

首先,咋們來看一下這次分享的驗證碼產生類別的產生流程圖:

##能看到此圖描述的編碼生成池對應的是幾個不同的編碼內容,這裡主要根據參數設定允許同時獲取不同編碼內容,從而到達文字,拼音,漢字組合而成驗證碼,具體

規則設定由參數而定;

» 驗證碼產生池代碼的解析

#首先,由上面流程圖分析的內容能看出,這個驗證碼產生池子需要並行取得不同類型驗證碼數據,才能滿足組合的驗證碼,因此有了下面的程式碼:


/// <summary>
 /// 创建验证码
 /// </summary>
 /// <param name="codeType">1:小写拼音 2:大写拼音 3:数字 4:汉字</param>
 /// <returns></returns>
 public static string CreateCode(string codeType = "1|2|3|4")
 {
 var code = string.Empty;
 try
 {
 if (string.IsNullOrWhiteSpace(codeType) || codeType.IndexOf(&#39;|&#39;) < 0) { codeType = "1|2|3|4"; }
 var codeTypeArr = codeType.Split(new char[] { &#39;|&#39; }, StringSplitOptions.RemoveEmptyEntries);
 var strLen = codeTypeArr.Length;
 //任务
 Task<string>[] taskArr = new Task<string>[strLen];
 for (int i = 0; i < strLen; i++)
 {
  var val = codeTypeArr[i];
  switch (val)
  {
  case "1": //小写拼音
  taskArr[i] = Task.Factory.StartNew<string>(() => { return GetPinYinOrUpper(false); });
  break;
  case "2": //大写拼音
  taskArr[i] = Task.Factory.StartNew<string>(() => { return GetPinYinOrUpper(); });
  break;
  case "3": //数字
  taskArr[i] = Task.Factory.StartNew<string>(() => { return GetShuZi(); });
  break;
  case "4": //汉字
  taskArr[i] = Task.Factory.StartNew<string>(() => { return GetHanZi(); });
  break;
  default:
  break;
  }
 }
 //等待完成 30s
 Task.WaitAll(taskArr, TimeSpan.FromSeconds(30));
 foreach (var item in taskArr)
 {
  code += item.Result;
 }
 }
 catch (Exception ex)
 {
 code = "我爱祖国";
 }
 return code;
 }
登入後複製

這裡繼續使用了關鍵字Task,來分發任務來取得不同的驗證碼內容,個人認為最主要的還是透過參數設定

string codeType = "1|2|3|4" ,來決定驗證碼的組合方式,這樣也達到了驗證碼格式的多樣性;

» 把驗證程式碼畫到圖片上

首先,咋們要明確的是要吧文字畫在某個圖片上,那就需要用到Graphics關鍵字,以此來建立畫布把咋們的驗證編碼畫到圖片上,這裡先上代碼:


/// <summary>
 /// 生成验证码图片流
 /// </summary>
 /// <param name="code">验证码文字</param>
 /// <returns>流</returns>
 public static byte[] CreateValidateCodeStream(string code = "我爱祖国", int fontSize = 18, int width = 0, int height = 0, string fontFamily = "华文楷体")
 {
 var bb = new byte[0];
 //初始化画布
 var padding = 2;
 var len = code.Length;
 width = width <= 0 ? fontSize * 2 * (len - 1) + padding * 4 : width;
 height = height <= 0 ? fontSize * 2 : height;
 var image = new Bitmap(width, height);
 var g = Graphics.FromImage(image);
 try
 {
 var random = new Random();
 //清空背景色
 g.Clear(Color.White);
 //画横向中间干扰线
 var x1 = 0;
 var y1 = height / 2;
 var x2 = width;
 var y2 = y1;
 g.DrawLine(new Pen(Color.DarkRed), x1, y1, x2, y2);
 //字体
 var font = new Font(fontFamily, fontSize, (FontStyle.Bold | FontStyle.Italic));
 var brush = new LinearGradientBrush(new Rectangle(0, 0, image.Width, image.Height),
  Color.Blue, Color.DarkRed, 1f, true);
 //画文字
 var stringFomart = new StringFormat();
 //垂直居中
 stringFomart.LineAlignment = StringAlignment.Center;
 //水平居中
 stringFomart.Alignment = StringAlignment.Center;
 var rf = new Rectangle(Point.Empty, new Size(width, height));
 g.DrawString(code, font, brush, rf, stringFomart);
 //画图片的前景干扰点
 for (int i = 0; i < 100; i++)
 {
  var x = random.Next(image.Width);
  var y = random.Next(image.Height);
  image.SetPixel(x, y, Color.FromArgb(random.Next()));
 }
 //画图片的边框线
 g.DrawRectangle(new Pen(Color.Silver), 0, 0, image.Width - 1, image.Height - 1);
 //保存图片流
 var stream = new MemoryStream();
 image.Save(stream, ImageFormat.Jpeg);
 //输出图片流
 bb = stream.ToArray();
 }
 catch (Exception ex) { }
 finally
 {
 g.Dispose();
 image.Dispose();
 }
 return bb;
 }
登入後複製

這個列出畫驗證碼圖片方法的關鍵點:

1. 圖片的高和寬度需要設置,這個根據不同

頁面佈局方式而定,所以這裡吧高和寬用作參數傳遞

2. 幹擾線:通常驗證碼圖片都以一兩條幹擾線,主要防止某些惡意用戶使用圖片識別軟體進行不正規破解請求,我在這裡幹擾線只設定了橫向居中的一天直線程式碼如:

g.DrawLine(new Pen(Color.DarkRed), x1, y1, x2, y2);

# 3. 字體:一個好看的字體通常也一種使用者體驗,因此這裡根據需要參數傳遞字體;

4. 驗證程式碼位於圖片縱橫向居中,這裡的關鍵程式碼是:


 var stringFomart = new StringFormat();
 //垂直居中
 stringFomart.LineAlignment = StringAlignment.Center;
 //水平居中
 stringFomart.Alignment = StringAlignment.Center;
登入後複製

5.  

g.DrawString(code, font, brush, rf, stringFomart); 主要用來把文字畫到圖片上,這是最關鍵的地方

6. 咋們通常都是吧驗證碼弄成圖片流,而不是真的生成一個實體的驗證碼圖片保存到伺服器上,不然這樣伺服器很快就會磁碟不足,所以


 //保存图片流
 var stream = new MemoryStream();
 image.Save(stream, ImageFormat.Jpeg);
 //输出图片流
 bb = stream.ToArray();
登入後複製

這句話的重要性也不可忽視,主要就把畫的內容保存到流中方便使用

7. 最後千萬不用忘了使用Dispose釋放畫布

» mvc登入操作測試驗證碼正確性

有了上面驗證碼產生類別產生好的驗證碼圖片,那我們還需要測試驗證下正確性和效果;下面我們使用mvc架構來做測試,先建立一個驗證碼測試Action並產生對應試圖ValidCode.cshtml文件,然後自訂幾個不同格式的驗證碼取得Action,程式碼如下:


public FileResult GetValidateCode()
 {
 //返回的验证码文字
 var code = string.Empty;
 var bb_code = ValidateCode.GetValidateCodeStream(ref code);

 return File(bb_code, "image/jpeg");
 }
 public FileResult GetValidateCode01()
 {
 var code = string.Empty;
 var bb_code = ValidateCode.GetValidateCodeStream(ref code, "1|2|3|4");
 return File(bb_code, "image/jpeg");
 }
 public FileResult GetValidateCode02()
 {
 var code = string.Empty;
 var bb_code = ValidateCode.GetValidateCodeStream(ref code, "4|3|2|1");
 return File(bb_code, "image/jpeg");
 }
 public FileResult GetValidateCode03()
 {
 var code = string.Empty;
 var bb_code = ValidateCode.GetValidateCodeStream(ref code, "2|2|2|2");
 return File(bb_code, "image/jpeg");
 }
 public FileResult GetValidateCode04()
 {
 var code = string.Empty;
 var bb_code = ValidateCode.GetValidateCodeStream(ref code, "4|4|4|4");
 return File(bb_code, "image/jpeg");
 }
 public FileResult GetValidateCode05()
 {
 var code = string.Empty;
 var bb_code = ValidateCode.GetValidateCodeStream(ref code, "1|1|1|1");
 return File(bb_code, "image/jpeg");
 }
登入後複製

感覺上幾乎一模一樣,只是對應的參數不一樣,這裡遵循的方法GetValidateCodeStream參數codeType格式是:為空表示自由組合  1:小寫拼音2:大寫拼音3:數字4:漢字;然後我們往試圖中填寫如下代碼:


#

<h2>神牛 - 验证码实例</h2>
<p class="container " id="appVue">
 <table class="table table-bordered text-left">
 <tbody>
 <tr>
 <td>全部随机</td>
 <td>
  <img src="/home/GetValidateCode" src="/home/GetValidateCode" id="imgCode" />
  <input type="text" name="code" placeholder="请输入验证码" class="form-control" />
  <button class="btn btn-default">登 录</button>
  <span id="msg" style="color:red"></span>
 </td>
 </tr>
 <tr>
 <td>小写|大写|数字|汉字</td>
 <td><img src="/home/GetValidateCode01" src="/home/GetValidateCode01" /></td>
 </tr>
 <tr>
 <td>汉字|数字|大写|小写</td>
 <td><img src="/home/GetValidateCode02" src="/home/GetValidateCode02" /></td>
 </tr>
 <tr>
 <td>全部大写</td>
 <td><img src="/home/GetValidateCode03" src="/home/GetValidateCode03" /></td>
 </tr>
 <tr>
 <td>全部汉字</td>
 <td><img src="/home/GetValidateCode04" src="/home/GetValidateCode04" /></td>
 </tr>
 <tr>
 <td>全部小写</td>
 <td><img src="/home/GetValidateCode05" src="/home/GetValidateCode05" /></td>
 </tr>
 </tbody>
 </table>
</p>
登入後複製

好了咋們生成下項目,看下效果圖如下:

能从图中看到我们验证码格式的不同之处,这也是文章开头说的验证码格式的多样性,当然可能还有其他组成格式请允许我暂时忽略,下面我们来做一个点击图片获取新验证码的功能和点击登录按钮去后台程序判断验证码是否匹配的例子,先来修改试图界面代码如下:


@{
 ViewBag.Title = "ValidtCode";
}
<h2>神牛 - 验证码实例</h2>
<p class="container " id="appVue">
 <table class="table table-bordered text-left">
 <tbody>
 <tr>
 <td>全部随机</td>
 <td>
  <img src="/home/GetValidateCode" src="/home/GetValidateCode" id="imgCode" />
  <input type="text" name="code" placeholder="请输入验证码" class="form-control" />
  <button class="btn btn-default">登 录</button>
  <span id="msg" style="color:red"></span>
 </td>
 </tr>
 <tr>
 <td>小写|大写|数字|汉字</td>
 <td><img src="/home/GetValidateCode01" src="/home/GetValidateCode01" /></td>
 </tr>
 <tr>
 <td>汉字|数字|大写|小写</td>
 <td><img src="/home/GetValidateCode02" src="/home/GetValidateCode02" /></td>
 </tr>
 <tr>
 <td>全部大写</td>
 <td><img src="/home/GetValidateCode03" src="/home/GetValidateCode03" /></td>
 </tr>
 <tr>
 <td>全部汉字</td>
 <td><img src="/home/GetValidateCode04" src="/home/GetValidateCode04" /></td>
 </tr>
 <tr>
 <td>全部小写</td>
 <td><img src="/home/GetValidateCode05" src="/home/GetValidateCode05" /></td>
 </tr>
 </tbody>
 </table>
</p>

登入後複製

然后在Controller中增加如下登录验证代码:


public JsonResult UserLogin(string code)
 {
 var data = new Stage.Com.Extend.StageModel.MoData();
 if (string.IsNullOrWhiteSpace(code)) { data.Msg = "验证码不能为空"; return Json(data); }
 var compareCode = Session["code"];
 if (!compareCode.Equals(code)) { data.Msg = "验证码错误"; return Json(data); }
 data.IsOk = true;
 data.Msg = "验证码验证成功";
 return Json(data);
 }
 public FileResult GetValidateCode()
 {
 //返回的验证码文字
 var code = string.Empty;
 var bb_code = ValidateCode.GetValidateCodeStream(ref code);

 var key = "code";
 if (Session[key] != null)
 {
 Session.Remove(key);
 }
 Session[key] = code;
 return File(bb_code, "image/jpeg");
 }
登入後複製

由于我这里无法截动态图,所点击测试获取验证码我这里直接给出线上的一个例子,各位可以试试:http://lovexins.com:1001/home/ValidCode,点击获取新验证码的关键代码是: $(this).attr("src", src); 重新给img元素的scr赋值,不过这里要注意由于浏览器缓存的原因,这里赋值的时候需要加上一个动态参数,我这里是使用时间作为请求参数,因此有了以下的代码: $(this).attr("src") + "?t=" + nowTime; 这是特别的地方需要注意;好了咋们来直接测试登陆是否能从后端判断验证码是否正确匹配吧,这里用的是session来保存获取验证码图片返回的验证代码,然后在登陆时候判断用户数据的验证码是否和后台session的验证一样:

验证失败:

验证成功:

好了测试用例就这么多,如果您觉得我这个验证码生成例子还可以并且您希望使用那么请注意,参数的传递,不同得到的验证码格式不同,主要方法是:


/// <summary>
 /// 获取验证码图片流
 /// </summary>
 /// <param name="codeLen">验证码个数(codeType设置 > codeLen设置)</param>
 /// <param name="codeType">为空表示自由组合 1:小写拼音 2:大写拼音 3:数字 4:汉字</param>
 /// <returns></returns>
 public static byte[] GetValidateCodeStream(ref string code, string codeType = "", int codeLen = 0, int fontSize = 18, int width = 120, int height = 30)
 {
 //为空自由组合
 if (string.IsNullOrWhiteSpace(codeType))
 {
 for (int i = 0; i < codeLen; i++)
 {
  codeType += rm.Next(1, 5) + "|";
 }
 }
 code = CreateCode(codeType);
 return CreateValidateCodeStream(code, fontSize, width: width, height: height);
 }
登入後複製

具体参数各位可以看下备注,我这里顺便打包下代码,方便分享和使用:验证码生成示例

以上是實作一個驗證碼產生類別(含數字,拼音,漢字)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

如何在PDF中驗證簽名 如何在PDF中驗證簽名 Feb 18, 2024 pm 05:33 PM

我們通常會接收到政府或其他機構發送的PDF文件,有些文件有數位簽章。驗證簽名後,我們會看到SignatureValid訊息和一個綠色勾號。如果簽章未驗證,會顯示有效性未知。驗證簽名很重要,以下看看如何在PDF中進行驗證。如何在PDF中驗證簽名驗證PDF格式的簽名使其更可信,文件更容易被接受。您可以透過以下方式驗證PDF文件中的簽名。在AdobeReader中開啟PDF右鍵點選簽名,然後選擇顯示簽名屬性點選顯示簽署者憑證按鈕從「信任」標籤將簽名新增至「受信任的憑證」清單中點選驗證簽名以完成驗證讓

微信好友輔助驗證解封的詳細方法 微信好友輔助驗證解封的詳細方法 Mar 25, 2024 pm 01:26 PM

1.打開微信進入後,點選搜尋圖標,輸入微信團隊,點選下方的服務進入。 2、進入後,點選左下方的自助工具的選項。 3、點選後,在上方的選項內,點選解封/申訴輔助驗證的選項。

C++程式將一個數字四捨五入到n位小數 C++程式將一個數字四捨五入到n位小數 Sep 12, 2023 pm 05:13 PM

在任何語言中編寫程式時,將數字表示為輸出是一項有趣且重要的任務。對於整數類型(short、long或medium類型的資料),很容易將數字表示為輸出。對於浮點數(float或double類型),有時我們需要將其四捨五入到特定的小數位數。例如,如果我們想將52.24568表示為三位小數,需要進行一些預處理。在本文中,我們將介紹幾種技術,透過四捨五入將浮點數表示為特定的小數位數。在不同的方法中,使用類似C的格式化字串、使用精度參數以及使用數學函式庫中的round()函數是很重要的。讓我們逐一來看。帶有

如何使用PHP產生可刷新的圖片驗證碼 如何使用PHP產生可刷新的圖片驗證碼 Sep 13, 2023 am 11:54 AM

如何使用PHP產生可刷新的圖片驗證碼隨著網路的發展,為了防止惡意攻擊和機器自動操作現象,許多網站都使用了驗證碼來進行使用者驗證。其中一個常見的驗證碼類型就是圖片驗證碼,透過產生一張包含隨機字元的圖片,要求使用者輸入正確的字元才能進行後續操作。本文將介紹如何使用PHP產生可刷新的圖片驗證碼,並提供具體的程式碼範例。步驟一:建立驗證碼圖片首先,我們需要建立一個用於生

PHP 8 新功能:增加了驗證和簽名 PHP 8 新功能:增加了驗證和簽名 Mar 27, 2024 am 08:21 AM

PHP8是PHP的最新版本,為程式設計師帶來了更多的便利性和功能。這個版本特別關注安全性和效能,其中一個值得注意的新功能是增加了驗證和簽章功能。在本文中,我們將深入了解這些新的功能及其用途。驗證和簽名是電腦科學中非常重要的安全概念。它們通常用於確保傳輸的數據是完整和真實的。在處理線上交易和敏感資訊時,驗證和簽名變得尤為重要,因為如果有人能夠篡改數據,可能會對

如何產生線上答案中的錯題本 如何產生線上答案中的錯題本 Sep 25, 2023 am 10:24 AM

如何產生線上答題的錯題本在現今的資訊時代,網路答題已經成為了許多學生和教育工作者的常見任務。而錯題一直是學習過程中的難題之一,許多人都希望能夠方便地產生線上答案的錯題本,以便更好地複習和掌握知識。本文將介紹如何透過程式設計實現線上答題錯題本的生成功能,並提供具體的程式碼範例。第一步:建立網頁介面產生線上答題錯題本需要一個網頁介面來顯示題目和答案。可以使用HTML

如何使用Vue實現二維碼生成 如何使用Vue實現二維碼生成 Nov 07, 2023 am 09:57 AM

二維碼是現代社會中廣泛使用的一種資訊編碼方式,Vue是一款前端框架,如何使用Vue實現二維碼生成?一、了解二維碼產生的原理二維碼的生成原理是將一段文字或一段URL位址轉換成一張圖片,在這張圖片中編碼了文字或URL位址的資訊。二維碼產生可以使用第三方函式庫,本文介紹如何使用Qrcode.js函式庫來產生二維碼。 Qrcode.js是一款輕量、無依賴的二維碼產生函式庫。二

word目錄生成錯亂怎麼辦 word目錄生成錯亂怎麼辦 Feb 20, 2024 am 08:08 AM

word目錄產生錯亂怎麼辦隨著科技的發展,電子文檔已經成為我們日常工作和學習中不可或缺的一部分。而在編輯電子文檔時,尤其是長篇文章或論文中,目錄的產生是一個非常重要的步驟。目錄能夠方便讀者查找到文章的內容和架構,提升閱讀效率。然而,有時候我們在生成目錄的過程中會遇到一些問題,例如目錄生成出錯,順序混亂等。那麼,如果word目錄生成錯亂,我們該如何解決呢?首

See all articles