Home  >  Article  >  Backend Development  >  .net encapsulates a verification code generation class

.net encapsulates a verification code generation class

Y2J
Y2JOriginal
2017-05-06 11:26:341675browse

This article shares with you a verification code generation class that integrates 1: lowercase Pinyin; 2: uppercase Pinyin; 3: numbers; 4: Chinese characters. The examples in this chapter will also include a scenario where mvc uses verification code verification. It has a certain reference value. Let’s take a look at it with the editor.

What I’m sharing with you this time is a verification code generation class that integrates 1: Lowercase Pinyin 2: Uppercase Pinyin 3: Number 4: Chinese characters. Judging from the title, it looks very ordinary. Yes, it is very ordinary. However, when generating this verification code class, you can specify the rules of the verification code return format through parameters. More importantly, I hope it can bring some practicality to everyone. The examples in this chapter will also include a scenario where MVC uses verification code for verification. I hope you will like it.

» Verification code generation flow chart

» Analysis of verification code generation pool code

» Verification The code is drawn on picture

» mvc login operation tests the correctness of the verification code

Let’s share it step by step:

» Verification code generation flow chart

First of all, let’s take a look at the generation flow chart of the verification code generation class shared this time:

You can see that the encoding generation pool described in this picture corresponds to several different encoding contents. Here, it is mainly allowed to obtain different encoding contents at the same time according to the parameter settings, so as to achieve the combination of text, pinyin, and Chinese characters. Verification code, the specific rule setting depends on the parameters;

» Analysis of verification code generation pool code

First, analyze from the above flow chart It can be seen from the content that this verification code generation pool needs to obtain different types of verification code data in parallel to meet the combined verification code, so the following code is available:

/// <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;
 }

The keyword Task is continued to be used here, to Distribute tasks to obtain different verification code contents. Personally, I think the most important thing is to determine the combination of verification codes through parameter settings string codeType = "1|2|3|4" , this also achieves the diversity of verification code formats;

» Draw the verification code on the picture

First of all, what we need to make clear is that we need to draw the text On a certain picture, you need to use the Graphics keyword to create a canvas and draw our verification code on the picture. Here is the code:

/// <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;
 }

This lists the methods for drawing verification code pictures. The key points:

1. The height and width of the image need to be set. This depends on different page layout methods, so here the height and width are used as parameters to pass

2. Interference line: Usually the verification code image has one or two interference lines, mainly to prevent some malicious users from using image recognition software to make irregular cracking requests. Here, the interference line only has a straight line code that is horizontally centered, such as: g.DrawLine(new Pen(Color.DarkRed), x1, y1, x2, y2);

3. Font: A good-looking font is usually a User experience, so the font is passed here according to the required parameters;

4. The verification code is located in the vertical and horizontal center of the image. The key code here is:

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

5. g. DrawString(code, font, brush, rf, stringFomart); Mainly used to draw text onto pictures, this is the most critical part

6. We usually verify it The code is turned into an image stream instead of actually generating an entity verification code image and saving it to the server. Otherwise, the server will soon run out of disk, so the importance of

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

cannot be ignored. Mainly Just save the painting content to the stream for easy use

7. Finally, don’t forget to use Dispose to release the canvas

» mvc login operation to test the correctness of the verification code

With the verification code image generated by the verification code generation class above, we still need to test and verify the correctness and effect; below we use mvcarchitecture to do the test, first create a Verification code test Action and generate the corresponding ValidCode.cshtml file, and then customize several verification codes in different formats to obtain the Action. The code is as follows:

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");
 }

It feels almost exactly the same, except that it corresponds The parameters are different. The method followed here is the GetValidateCodeStream parameter codeType format: empty means free combination 1: Lowercase Pinyin 2: Uppercase Pinyin 3: Number 4: Chinese characters; then we fill in the following code in the view:

<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>

Okay, let’s generate the project and look at the renderings as follows:

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

@{
 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);
 }

【相关推荐】

1. ASP免费视频教程

2. ASP教程

3. 李炎恢ASP基础视频教程

The above is the detailed content of .net encapsulates a verification code generation class. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn